diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71594a4c..94046873 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,9 +17,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@v3 - - name: Set up Java uses: actions/setup-java@v4 with: @@ -30,7 +27,7 @@ jobs: cache: gradle - name: Set up Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/actions/setup-gradle@v4 - name: Run lints run: ./scripts/lint @@ -55,4 +52,3 @@ jobs: - name: Run tests run: ./scripts/test - diff --git a/.github/workflows/publish-sonatype.yml b/.github/workflows/publish-sonatype.yml index d0246884..a1f76188 100755 --- a/.github/workflows/publish-sonatype.yml +++ b/.github/workflows/publish-sonatype.yml @@ -29,11 +29,13 @@ jobs: uses: gradle/gradle-build-action@v2 - name: Publish to Sonatype - run: | + run: |- + export -- GPG_SIGNING_KEY_ID + printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD" + GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')" ./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" env: SONATYPE_USERNAME: ${{ secrets.BRAINTRUST_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.BRAINTRUST_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} - GPG_SIGNING_KEY_ID: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_KEY_ID || secrets.GPG_SIGNING_KEY_ID }} GPG_SIGNING_KEY: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} GPG_SIGNING_PASSWORD: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 88dee7a9..d9128fbc 100755 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -20,6 +20,5 @@ jobs: env: SONATYPE_USERNAME: ${{ secrets.BRAINTRUST_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.BRAINTRUST_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }} - GPG_SIGNING_KEY_ID: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_KEY_ID || secrets.GPG_SIGNING_KEY_ID }} GPG_SIGNING_KEY: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_KEY || secrets.GPG_SIGNING_KEY }} GPG_SIGNING_PASSWORD: ${{ secrets.BRAINTRUST_SONATYPE_GPG_SIGNING_PASSWORD || secrets.GPG_SIGNING_PASSWORD }} diff --git a/.gitignore b/.gitignore index 39c31e3e..4e81838d 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .prism.log .gradle .idea +.kotlin build codegen.log kls_database.db diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1b77f506..6538ca91 100755 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.7.0" + ".": "0.8.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index ac9200d3..24a7d1d7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/manugoyal%2Fbraintrust-sdk-9d216c8243fe39ba2ffe3bffaab0dba53f1c04b7216d22f9072f6611233de0c7.yml +configured_endpoints: 110 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/manugoyal%2Fbraintrust-sdk-f0d64ce0e0efde75f9c171f7f3c3d4a72f00a77abb3bc5a7d65b7be1e715689b.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0c5a5d..5898a8aa 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,128 @@ # Changelog +## 0.8.0 (2025-03-18) + +Full Changelog: [v0.7.0...v0.8.0](https://github.com/braintrustdata/braintrust-java/compare/v0.7.0...v0.8.0) + +### ⚠ BREAKING CHANGES + +* **client:** refactor multipart formdata impl ([#132](https://github.com/braintrustdata/braintrust-java/issues/132)) + +### Features + +* **api:** api update ([#64](https://github.com/braintrustdata/braintrust-java/issues/64)) ([f1d956d](https://github.com/braintrustdata/braintrust-java/commit/f1d956dec36db180eba1333303361fe577229fbd)) +* **api:** api update ([#66](https://github.com/braintrustdata/braintrust-java/issues/66)) ([02b0490](https://github.com/braintrustdata/braintrust-java/commit/02b0490c081fc51c4c11b12cf8592dc513ac7a1f)) +* **api:** api update ([#67](https://github.com/braintrustdata/braintrust-java/issues/67)) ([2ca59f7](https://github.com/braintrustdata/braintrust-java/commit/2ca59f78f8e775f10b4c09e040e7f55ec27612b1)) +* **api:** api update ([#68](https://github.com/braintrustdata/braintrust-java/issues/68)) ([288a26d](https://github.com/braintrustdata/braintrust-java/commit/288a26dc55ba27313879a00ace18304408adefe9)) +* **api:** manual updates ([#100](https://github.com/braintrustdata/braintrust-java/issues/100)) ([8aea924](https://github.com/braintrustdata/braintrust-java/commit/8aea924ce9c2992c1f620f63c077de8e508852f6)) +* **api:** manual updates ([#107](https://github.com/braintrustdata/braintrust-java/issues/107)) ([893c7c9](https://github.com/braintrustdata/braintrust-java/commit/893c7c9d9397aa0b5abd0b13f8d3d889aa2c6636)) +* **api:** manual updates ([#148](https://github.com/braintrustdata/braintrust-java/issues/148)) ([03f4bce](https://github.com/braintrustdata/braintrust-java/commit/03f4bce0a262fd275057a74fc5cc6736e9df6a70)) +* **api:** manual updates ([#149](https://github.com/braintrustdata/braintrust-java/issues/149)) ([98e4bf7](https://github.com/braintrustdata/braintrust-java/commit/98e4bf7ddd7fd4709b2c4bc12d6f208316f98ac0)) +* **api:** manual updates ([#150](https://github.com/braintrustdata/braintrust-java/issues/150)) ([be6e2a6](https://github.com/braintrustdata/braintrust-java/commit/be6e2a679a76caf1e7ef03422ef91087a2c75981)) +* **api:** manual updates ([#151](https://github.com/braintrustdata/braintrust-java/issues/151)) ([be0354d](https://github.com/braintrustdata/braintrust-java/commit/be0354dbb77893f24083ea294531d8f7a1e00309)) +* **api:** manual updates ([#91](https://github.com/braintrustdata/braintrust-java/issues/91)) ([5e9b07e](https://github.com/braintrustdata/braintrust-java/commit/5e9b07e8f84aff42457a97000302fa2e890282b2)) +* **api:** manual updates ([#93](https://github.com/braintrustdata/braintrust-java/issues/93)) ([3c635ad](https://github.com/braintrustdata/braintrust-java/commit/3c635adb8c1d2e6e26f20e764ac5b9de50b4f2db)) +* **api:** manual updates ([#95](https://github.com/braintrustdata/braintrust-java/issues/95)) ([0e97915](https://github.com/braintrustdata/braintrust-java/commit/0e97915cf7aaa7f1610d56b7c281c28b84ead0ac)) +* **api:** manual updates ([#96](https://github.com/braintrustdata/braintrust-java/issues/96)) ([711a5bc](https://github.com/braintrustdata/braintrust-java/commit/711a5bcf08739214cb62ef99a8de9e267c7afb34)) +* **api:** manual updates ([#97](https://github.com/braintrustdata/braintrust-java/issues/97)) ([f229777](https://github.com/braintrustdata/braintrust-java/commit/f229777ec23714e3e3adfdb6678cffccb13a89f9)) +* **api:** manual updates ([#98](https://github.com/braintrustdata/braintrust-java/issues/98)) ([d27a782](https://github.com/braintrustdata/braintrust-java/commit/d27a7828e50e8e0c91c6b9a527796d0352a8a554)) +* **api:** manual updates ([#99](https://github.com/braintrustdata/braintrust-java/issues/99)) ([eb3e689](https://github.com/braintrustdata/braintrust-java/commit/eb3e6891d822772b04258b63d3ecb1db96537186)) +* **client:** accept `InputStream` and `Path` for file params ([#136](https://github.com/braintrustdata/braintrust-java/issues/136)) ([92073d0](https://github.com/braintrustdata/braintrust-java/commit/92073d0365dcb479ba2565a41305f56f882fecb3)) +* **client:** add logging when debug env is set ([#106](https://github.com/braintrustdata/braintrust-java/issues/106)) ([0bad87e](https://github.com/braintrustdata/braintrust-java/commit/0bad87e1644242cfdbe21d92bf19d138536900f0)) +* **client:** allow configuring timeouts granularly ([#130](https://github.com/braintrustdata/braintrust-java/issues/130)) ([606ebb7](https://github.com/braintrustdata/braintrust-java/commit/606ebb74dcc339190eeefe2b072f273783445edc)) +* **client:** detect binary incompatible jackson versions ([#137](https://github.com/braintrustdata/braintrust-java/issues/137)) ([de216b5](https://github.com/braintrustdata/braintrust-java/commit/de216b560305cb737647cbc34e7775d84ee0e11e)) +* **client:** get rid of annoying checked exceptions ([#118](https://github.com/braintrustdata/braintrust-java/issues/118)) ([0aabe74](https://github.com/braintrustdata/braintrust-java/commit/0aabe74100f814d12b472e5f4d8344b851804d0a)) +* **client:** support `JsonField#asX()` for known values ([#114](https://github.com/braintrustdata/braintrust-java/issues/114)) ([550e1a8](https://github.com/braintrustdata/braintrust-java/commit/550e1a8e92513d874055b527c8b20188078fe312)) +* **client:** support raw response access ([#131](https://github.com/braintrustdata/braintrust-java/issues/131)) ([cc8b5a5](https://github.com/braintrustdata/braintrust-java/commit/cc8b5a5d66ca1a077e58cbf145e468effbfba2c3)) +* **client:** update enum `asX` methods ([#113](https://github.com/braintrustdata/braintrust-java/issues/113)) ([ed83ac5](https://github.com/braintrustdata/braintrust-java/commit/ed83ac52612873519062919eae567a1e82b3b221)) +* generate and publish docs ([#138](https://github.com/braintrustdata/braintrust-java/issues/138)) ([d951553](https://github.com/braintrustdata/braintrust-java/commit/d9515531787d8f63c33c977118ea6c58378ee7f9)) + + +### Bug Fixes + +* **client:** add missing `@JvmStatic` ([#124](https://github.com/braintrustdata/braintrust-java/issues/124)) ([c4e0b8a](https://github.com/braintrustdata/braintrust-java/commit/c4e0b8ad6755613242bcc135c36dd7538adb8c99)) +* **client:** mark some request bodies as optional ([#120](https://github.com/braintrustdata/braintrust-java/issues/120)) ([274c95c](https://github.com/braintrustdata/braintrust-java/commit/274c95c6df23554f747392fb51a50f3a327125af)) + + +### Chores + +* **api:** manual updates ([#72](https://github.com/braintrustdata/braintrust-java/issues/72)) ([b6c9f43](https://github.com/braintrustdata/braintrust-java/commit/b6c9f43a2a14533b88d39666809b5ee7ce670504)) +* **client:** expose `Optional`, not nullable, from `ClientOptions` ([#135](https://github.com/braintrustdata/braintrust-java/issues/135)) ([bd8a24d](https://github.com/braintrustdata/braintrust-java/commit/bd8a24d41ddc414c3797a303c2b48ecd643d772b)) +* **client:** refactor multipart formdata impl ([#132](https://github.com/braintrustdata/braintrust-java/issues/132)) ([a32b711](https://github.com/braintrustdata/braintrust-java/commit/a32b7113952189d2624dcbb534a6da5dc36a3224)) +* **client:** use deep identity methods for primitive array types ([#126](https://github.com/braintrustdata/braintrust-java/issues/126)) ([effc197](https://github.com/braintrustdata/braintrust-java/commit/effc19754eb651f3531959839e9a803d4b056587)) +* **deps:** bump jackson to 2.18.1 ([#101](https://github.com/braintrustdata/braintrust-java/issues/101)) ([1d5c887](https://github.com/braintrustdata/braintrust-java/commit/1d5c887b11473e110a197d004a278f9abf8ed4c4)) +* **docs:** add faq to readme ([#119](https://github.com/braintrustdata/braintrust-java/issues/119)) ([5b4d07f](https://github.com/braintrustdata/braintrust-java/commit/5b4d07fc3da4e77c62bdffddd4f6e215401755b2)) +* **docs:** reorganize readme ([#115](https://github.com/braintrustdata/braintrust-java/issues/115)) ([b65c599](https://github.com/braintrustdata/braintrust-java/commit/b65c5991e1451302fd20fb345d82c89fbd47bc80)) +* **internal:** add `.kotlin` to `.gitignore` ([#139](https://github.com/braintrustdata/braintrust-java/issues/139)) ([1e4c3e5](https://github.com/braintrustdata/braintrust-java/commit/1e4c3e584f71562c26dde78c3366c75e1e5dd8bb)) +* **internal:** add async service tests ([#125](https://github.com/braintrustdata/braintrust-java/issues/125)) ([5dc06c8](https://github.com/braintrustdata/braintrust-java/commit/5dc06c8acd281951e841146b1b16803f017c9948)) +* **internal:** add generated comment ([#154](https://github.com/braintrustdata/braintrust-java/issues/154)) ([28a3568](https://github.com/braintrustdata/braintrust-java/commit/28a35683de525b8de0ca345bb246ed537104788d)) +* **internal:** codegen related update ([#105](https://github.com/braintrustdata/braintrust-java/issues/105)) ([ad0fed3](https://github.com/braintrustdata/braintrust-java/commit/ad0fed3824772a29ce635f672c2feb6f7c2beb17)) +* **internal:** codegen related update ([#109](https://github.com/braintrustdata/braintrust-java/issues/109)) ([a8b7cd7](https://github.com/braintrustdata/braintrust-java/commit/a8b7cd7d1e5346b702483b336f9a1d9f71f38c11)) +* **internal:** codegen related update ([#111](https://github.com/braintrustdata/braintrust-java/issues/111)) ([029cbc7](https://github.com/braintrustdata/braintrust-java/commit/029cbc78bf94c707da26f3550db354480909bd78)) +* **internal:** codegen related update ([#117](https://github.com/braintrustdata/braintrust-java/issues/117)) ([aaaef18](https://github.com/braintrustdata/braintrust-java/commit/aaaef188d4fbe8ba97fcc55fe1dac15d527cf1ec)) +* **internal:** codegen related update ([#122](https://github.com/braintrustdata/braintrust-java/issues/122)) ([c9d3840](https://github.com/braintrustdata/braintrust-java/commit/c9d3840c4fded6c0ece296ceb60a5526c3d81c75)) +* **internal:** codegen related update ([#123](https://github.com/braintrustdata/braintrust-java/issues/123)) ([9dbc537](https://github.com/braintrustdata/braintrust-java/commit/9dbc537a6271bc2bbd2839515f77eeb58951e4ab)) +* **internal:** codegen related update ([#145](https://github.com/braintrustdata/braintrust-java/issues/145)) ([23f0da4](https://github.com/braintrustdata/braintrust-java/commit/23f0da4fecedf41ae2a2f573ed0f8e25938057cf)) +* **internal:** codegen related update ([#146](https://github.com/braintrustdata/braintrust-java/issues/146)) ([4a82e6f](https://github.com/braintrustdata/braintrust-java/commit/4a82e6f3159a2b6697f8dbe23304a693e0448ebb)) +* **internal:** don't use `JvmOverloads` in interfaces ([84daad7](https://github.com/braintrustdata/braintrust-java/commit/84daad738819f265ff28ab6c351008a7018e0340)) +* **internal:** get rid of configuration cache ([#116](https://github.com/braintrustdata/braintrust-java/issues/116)) ([1a69b73](https://github.com/braintrustdata/braintrust-java/commit/1a69b73fdc5eb657e72fd3b3d8d3c4f34378cbc3)) +* **internal:** improve sync service tests ([5dc06c8](https://github.com/braintrustdata/braintrust-java/commit/5dc06c8acd281951e841146b1b16803f017c9948)) +* **internal:** make body class constructors private ([b417ac7](https://github.com/braintrustdata/braintrust-java/commit/b417ac7d07cc916a3928a17a57406b08ed014fa0)) +* **internal:** make body classes for multipart requests ([b417ac7](https://github.com/braintrustdata/braintrust-java/commit/b417ac7d07cc916a3928a17a57406b08ed014fa0)) +* **internal:** make test classes internal ([#153](https://github.com/braintrustdata/braintrust-java/issues/153)) ([f4d9990](https://github.com/braintrustdata/braintrust-java/commit/f4d99903225690cfb6fad53ac26fee5c3615977f)) +* **internal:** misc formatting changes ([b417ac7](https://github.com/braintrustdata/braintrust-java/commit/b417ac7d07cc916a3928a17a57406b08ed014fa0)) +* **internal:** reenable warnings as errors ([#141](https://github.com/braintrustdata/braintrust-java/issues/141)) ([84daad7](https://github.com/braintrustdata/braintrust-java/commit/84daad738819f265ff28ab6c351008a7018e0340)) +* **internal:** refactor `ErrorHandlingTest` ([#129](https://github.com/braintrustdata/braintrust-java/issues/129)) ([f61300b](https://github.com/braintrustdata/braintrust-java/commit/f61300b640f71f7d5ce0dee685b0d0524da59d08)) +* **internal:** refactor `PhantomReachableClosingAsyncStreamResponse` impl ([#110](https://github.com/braintrustdata/braintrust-java/issues/110)) ([d1647df](https://github.com/braintrustdata/braintrust-java/commit/d1647dff5977260e2346ad1eeaa5105cc82f8463)) +* **internal:** refactor `ServiceParamsTest` ([#127](https://github.com/braintrustdata/braintrust-java/issues/127)) ([4104744](https://github.com/braintrustdata/braintrust-java/commit/410474405bf5b56695aea53e7d560d7cc48bc144)) +* **internal:** refactor query param serialization impl and tests ([#156](https://github.com/braintrustdata/braintrust-java/issues/156)) ([f141195](https://github.com/braintrustdata/braintrust-java/commit/f1411950e6f4807ac2ec5f34ed12ecbc70b51fad)) +* **internal:** remove unnecessary non-null asserts in tests ([274c95c](https://github.com/braintrustdata/braintrust-java/commit/274c95c6df23554f747392fb51a50f3a327125af)) +* **internal:** remove unused script ([#147](https://github.com/braintrustdata/braintrust-java/issues/147)) ([6eee272](https://github.com/braintrustdata/braintrust-java/commit/6eee2722878aa0bfd85f8f11b6a99fb5aa2b4036)) +* **internal:** rename internal body classes ([b417ac7](https://github.com/braintrustdata/braintrust-java/commit/b417ac7d07cc916a3928a17a57406b08ed014fa0)) +* **internal:** update some formatting in `Values.kt` ([550e1a8](https://github.com/braintrustdata/braintrust-java/commit/550e1a8e92513d874055b527c8b20188078fe312)) +* **internal:** update variable names in tests ([#142](https://github.com/braintrustdata/braintrust-java/issues/142)) ([e8882a7](https://github.com/braintrustdata/braintrust-java/commit/e8882a710bff95c91accdcd7bd293f24a724fb7f)) +* **internal:** use `assertNotNull` in tests for type narrowing ([274c95c](https://github.com/braintrustdata/braintrust-java/commit/274c95c6df23554f747392fb51a50f3a327125af)) +* **internal:** use `getOrNull` instead of `orElse(null)` ([#140](https://github.com/braintrustdata/braintrust-java/issues/140)) ([1db71f8](https://github.com/braintrustdata/braintrust-java/commit/1db71f8bc37728717ecbfcffb31f6b3afbe4380a)) +* **internal:** use better test example values ([#112](https://github.com/braintrustdata/braintrust-java/issues/112)) ([b417ac7](https://github.com/braintrustdata/braintrust-java/commit/b417ac7d07cc916a3928a17a57406b08ed014fa0)) +* rebuild project due to codegen change ([#69](https://github.com/braintrustdata/braintrust-java/issues/69)) ([a7c0606](https://github.com/braintrustdata/braintrust-java/commit/a7c0606dca2139ba230c5d4813dcf76f1ec59d08)) +* rebuild project due to codegen change ([#70](https://github.com/braintrustdata/braintrust-java/issues/70)) ([ccb8dd5](https://github.com/braintrustdata/braintrust-java/commit/ccb8dd583d9783e0466503fa848a1ef5fd577e20)) +* rebuild project due to codegen change ([#71](https://github.com/braintrustdata/braintrust-java/issues/71)) ([0c35214](https://github.com/braintrustdata/braintrust-java/commit/0c35214c2e1b903f741cf39c6a4d7289b13b6271)) +* rebuild project due to codegen change ([#73](https://github.com/braintrustdata/braintrust-java/issues/73)) ([a7a6379](https://github.com/braintrustdata/braintrust-java/commit/a7a6379e2b4e7a8944aa89df8de05ca116db8af8)) +* rebuild project due to codegen change ([#74](https://github.com/braintrustdata/braintrust-java/issues/74)) ([d665d0f](https://github.com/braintrustdata/braintrust-java/commit/d665d0f6cfd44d1bee4ea5dd02d00c0a63203b0c)) +* rebuild project due to codegen change ([#75](https://github.com/braintrustdata/braintrust-java/issues/75)) ([9ac5669](https://github.com/braintrustdata/braintrust-java/commit/9ac566913ab54368b5e1eb10c5e6c20fc86ff75a)) +* rebuild project due to codegen change ([#76](https://github.com/braintrustdata/braintrust-java/issues/76)) ([6498c99](https://github.com/braintrustdata/braintrust-java/commit/6498c997bc0fb2ae68e842ab6b69110115fa458b)) +* rebuild project due to codegen change ([#77](https://github.com/braintrustdata/braintrust-java/issues/77)) ([7c9b2ad](https://github.com/braintrustdata/braintrust-java/commit/7c9b2adb46f8e24d9a3c908400596d96795b8ede)) +* rebuild project due to codegen change ([#78](https://github.com/braintrustdata/braintrust-java/issues/78)) ([fa5ee1f](https://github.com/braintrustdata/braintrust-java/commit/fa5ee1f34562b8ac88122f183ee307aec99ff496)) +* rebuild project due to codegen change ([#79](https://github.com/braintrustdata/braintrust-java/issues/79)) ([9e17de0](https://github.com/braintrustdata/braintrust-java/commit/9e17de04225a4a334fe068f5cbd7e3116c765782)) +* rebuild project due to codegen change ([#80](https://github.com/braintrustdata/braintrust-java/issues/80)) ([223ed2e](https://github.com/braintrustdata/braintrust-java/commit/223ed2e21d18538cff3875f3697b2c0ded1b4ad3)) +* rebuild project due to codegen change ([#81](https://github.com/braintrustdata/braintrust-java/issues/81)) ([44f5fbe](https://github.com/braintrustdata/braintrust-java/commit/44f5fbe68fcb12f0d08a091c88c39bf87f8855af)) +* rebuild project due to codegen change ([#83](https://github.com/braintrustdata/braintrust-java/issues/83)) ([c9d6eae](https://github.com/braintrustdata/braintrust-java/commit/c9d6eae2658ce543a3ccba996373b923e4371cd7)) +* rebuild project due to codegen change ([#84](https://github.com/braintrustdata/braintrust-java/issues/84)) ([8f2a24b](https://github.com/braintrustdata/braintrust-java/commit/8f2a24b0683f51df845f3a433d66994288149e6a)) +* rebuild project due to codegen change ([#86](https://github.com/braintrustdata/braintrust-java/issues/86)) ([d83611f](https://github.com/braintrustdata/braintrust-java/commit/d83611fa8e3155f295f276573235d1bfd6f68371)) +* rebuild project due to codegen change ([#88](https://github.com/braintrustdata/braintrust-java/issues/88)) ([2e62835](https://github.com/braintrustdata/braintrust-java/commit/2e62835d07807e4e1aa018180fac6ca3de574e8e)) +* rebuild project due to codegen change ([#90](https://github.com/braintrustdata/braintrust-java/issues/90)) ([e353324](https://github.com/braintrustdata/braintrust-java/commit/e35332464b9e4a83bef95f90866c0de79bc8c0ff)) +* rebuild project due to codegen change ([#94](https://github.com/braintrustdata/braintrust-java/issues/94)) ([1cd427d](https://github.com/braintrustdata/braintrust-java/commit/1cd427d2b43bbfb35c1ef70ae0e20ff7c66bb876)) + + +### Documentation + +* add `build` method comments ([#155](https://github.com/braintrustdata/braintrust-java/issues/155)) ([6b504cb](https://github.com/braintrustdata/braintrust-java/commit/6b504cbb091ddbfff7b2487dd143cab9e3d4da01)) +* add immutability explanation to readme ([#121](https://github.com/braintrustdata/braintrust-java/issues/121)) ([6a15c6f](https://github.com/braintrustdata/braintrust-java/commit/6a15c6f103419b9ebd420a5a40de9b675c5302f0)) +* add more phantom reachability docs ([d1647df](https://github.com/braintrustdata/braintrust-java/commit/d1647dff5977260e2346ad1eeaa5105cc82f8463)) +* add raw response readme documentation ([#133](https://github.com/braintrustdata/braintrust-java/issues/133)) ([711d655](https://github.com/braintrustdata/braintrust-java/commit/711d6554708df00be676d724775d090a8f1f5723)) +* deduplicate and refine comments ([#152](https://github.com/braintrustdata/braintrust-java/issues/152)) ([73fb462](https://github.com/braintrustdata/braintrust-java/commit/73fb462b4574596a30820dbab116ba57fab47460)) +* document `JsonValue` construction in readme ([#144](https://github.com/braintrustdata/braintrust-java/issues/144)) ([33fa7ab](https://github.com/braintrustdata/braintrust-java/commit/33fa7ab33b83c408b14fc770b451ac9bb10bd1ca)) +* note required fields in `builder` javadoc ([#134](https://github.com/braintrustdata/braintrust-java/issues/134)) ([c0d11e5](https://github.com/braintrustdata/braintrust-java/commit/c0d11e5cd44c38cb272cab21f18432e25dc204a0)) +* readme parameter tweaks ([5dc06c8](https://github.com/braintrustdata/braintrust-java/commit/5dc06c8acd281951e841146b1b16803f017c9948)) +* revise readme docs about nested params ([#143](https://github.com/braintrustdata/braintrust-java/issues/143)) ([0a06490](https://github.com/braintrustdata/braintrust-java/commit/0a06490b643d90b0666d2f3505dd20e8d519251c)) +* update URLs from stainlessapi.com to stainless.com ([#128](https://github.com/braintrustdata/braintrust-java/issues/128)) ([57e17de](https://github.com/braintrustdata/braintrust-java/commit/57e17de51ce9372dee4dab1f3ad67a040d7900bb)) + + +### Styles + +* **internal:** move identity methods to bottom of error class ([#104](https://github.com/braintrustdata/braintrust-java/issues/104)) ([fd04071](https://github.com/braintrustdata/braintrust-java/commit/fd04071cbeb2abb04310bd4389279dbaadb9a302)) +* **internal:** reduce verbosity of identity methods ([#103](https://github.com/braintrustdata/braintrust-java/issues/103)) ([f09c5a0](https://github.com/braintrustdata/braintrust-java/commit/f09c5a01a41e464796e781e9923a96f501786242)) + ## 0.7.0 (2024-10-01) Full Changelog: [v0.6.0...v0.7.0](https://github.com/braintrustdata/braintrust-java/compare/v0.6.0...v0.7.0) diff --git a/LICENSE b/LICENSE index 5e03e95a..f3b9e7e5 100755 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Braintrust + Copyright 2025 Braintrust Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 31a23686..99c7eb77 100644 --- a/README.md +++ b/README.md @@ -2,179 +2,228 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.braintrustdata.api/braintrust-java)](https://central.sonatype.com/artifact/com.braintrustdata.api/braintrust-java/0.7.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.braintrustdata.api/braintrust-java)](https://central.sonatype.com/artifact/com.braintrustdata.api/braintrust-java/0.8.0) +[![javadoc](https://javadoc.io/badge2/com.braintrustdata.api/braintrust-java/0.8.0/javadoc.svg)](https://javadoc.io/doc/com.braintrustdata.api/braintrust-java/0.8.0) -The Braintrust Java SDK provides convenient access to the Braintrust REST API from applications written in Java. It includes helper classes with helpful types and documentation for every request and response property. +The Braintrust Java SDK provides convenient access to the Braintrust REST API from applications written in Java. The Braintrust Java SDK is similar to the Braintrust Kotlin SDK but with minor differences that make it more ergonomic for use in Java, such as `Optional` instead of nullable values, `Stream` instead of `Sequence`, and `CompletableFuture` instead of suspend functions. -It is generated with [Stainless](https://www.stainlessapi.com/). +It is generated with [Stainless](https://www.stainless.com/). -## Documentation +The REST API documentation can be found on [www.braintrustdata.com](https://www.braintrustdata.com/docs/api/spec). Javadocs are also available on [javadoc.io](https://javadoc.io/doc/com.braintrustdata.api/braintrust-java/0.7.0). -The REST API documentation can be found on [www.braintrustdata.com](https://www.braintrustdata.com/docs/api/spec). - ---- - -## Getting started - -### Install dependencies - -#### Gradle +## Installation +### Gradle + ```kotlin -implementation("com.braintrustdata.api:braintrust-java:0.7.0") +implementation("com.braintrustdata.api:braintrust-java:0.8.0") ``` -#### Maven +### Maven ```xml com.braintrustdata.api braintrust-java - 0.7.0 + 0.8.0 ``` -### Configure the client +## Requirements -Use `BraintrustOkHttpClient.builder()` to configure the client. +This library requires Java 8 or later. -Alternately, set the environment with `BRAINTRUST_API_KEY`, and use `BraintrustOkHttpClient.fromEnv()` to read from the environment. +## Usage ```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; + +// Configures using the `BRAINTRUST_API_KEY` environment variable BraintrustClient client = BraintrustOkHttpClient.fromEnv(); -// Note: you can also call fromEnv() from the client builder, for example if you need to set additional properties -BraintrustClient client = BraintrustOkHttpClient.builder() - .fromEnv() - // ... set properties on the builder +ProjectCreateParams params = ProjectCreateParams.builder() + .name("foobar") .build(); +Project project = client.projects().create(params); ``` -| Property | Environment variable | Required | Default value | -| -------- | -------------------- | -------- | ------------- | -| apiKey | `BRAINTRUST_API_KEY` | false | — | +## Client configuration -Read the documentation for more configuration options. +Configure the client using environment variables: ---- +```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; -### Example: creating a resource +// Configures using the `BRAINTRUST_API_KEY` environment variable +BraintrustClient client = BraintrustOkHttpClient.fromEnv(); +``` -To create a new project, first use the `ProjectCreateParams` builder to specify attributes, -then pass that to the `create` method of the `projects` service. +Or manually: ```java -import com.braintrustdata.api.models.Project; -import com.braintrustdata.api.models.ProjectCreateParams; +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; -ProjectCreateParams params = ProjectCreateParams.builder() - .name("foobar") +BraintrustClient client = BraintrustOkHttpClient.builder() + .apiKey("My API Key") .build(); -Project project = client.projects().create(params); ``` -### Example: listing resources - -The Braintrust API provides a `list` method to get a paginated list of projects. -You can retrieve the first page by: +Or using a combination of the two approaches: ```java -import com.braintrustdata.api.models.Page; -import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; -ProjectListPage page = client.projects().list(); -for (Project project : page.objects()) { - System.out.println(project); -} +BraintrustClient client = BraintrustOkHttpClient.builder() + // Configures using the `BRAINTRUST_API_KEY` environment variable + .fromEnv() + .apiKey("My API Key") + .build(); ``` -See [Pagination](#pagination) below for more information on transparently working with lists of objects without worrying about fetching each page. +See this table for the available options: + +| Setter | Environment variable | Required | Default value | +| -------- | -------------------- | -------- | ------------- | +| `apiKey` | `BRAINTRUST_API_KEY` | false | - | + +> [!TIP] +> Don't create more than one client in the same application. Each client has a connection pool and +> thread pools, which are more efficient to share between requests. + +## Requests and responses + +To send a request to the Braintrust API, build an instance of some `Params` class and pass it to the corresponding client method. When the response is received, it will be deserialized into an instance of a Java class. ---- +For example, `client.projects().create(...)` should be called with an instance of `ProjectCreateParams`, and it will return an instance of `Project`. -## Requests +## Immutability -### Parameters and bodies +Each class in the SDK has an associated [builder](https://blogs.oracle.com/javamagazine/post/exploring-joshua-blochs-builder-design-pattern-in-java) or factory method for constructing it. -To make a request to the Braintrust API, you generally build an instance of the appropriate `Params` class. +Each class is [immutable](https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) once constructed. If the class has an associated builder, then it has a `toBuilder()` method, which can be used to convert it back to a builder for making a modified copy. -In [Example: creating a resource](#example-creating-a-resource) above, we used the `ProjectCreateParams.builder()` to pass to -the `create` method of the `projects` service. +Because each class is immutable, builder modification will _never_ affect already built class instances. -Sometimes, the API may support other properties that are not yet supported in the Java SDK types. In that case, -you can attach them using the `putAdditionalProperty` method. +## Asynchronous execution + +The default client is synchronous. To switch to asynchronous execution, call the `async()` method: ```java -import com.braintrustdata.api.models.core.JsonValue; +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; +import java.util.concurrent.CompletableFuture; + +// Configures using the `BRAINTRUST_API_KEY` environment variable +BraintrustClient client = BraintrustOkHttpClient.fromEnv(); + ProjectCreateParams params = ProjectCreateParams.builder() - // ... normal properties - .putAdditionalProperty("secret_param", JsonValue.from("4242")) + .name("foobar") .build(); +CompletableFuture project = client.async().projects().create(params); ``` -## Responses +Or create an asynchronous client from the beginning: -### Response validation +```java +import com.braintrustdata.api.client.BraintrustClientAsync; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync; +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; +import java.util.concurrent.CompletableFuture; -When receiving a response, the Braintrust Java SDK will deserialize it into instances of the typed model classes. In rare cases, the API may return a response property that doesn't match the expected Java type. If you directly access the mistaken property, the SDK will throw an unchecked `BraintrustInvalidDataException` at runtime. If you would prefer to check in advance that that response is completely well-typed, call `.validate()` on the returned model. +// Configures using the `BRAINTRUST_API_KEY` environment variable +BraintrustClientAsync client = BraintrustOkHttpClientAsync.fromEnv(); -```java -Project project = client.projects().create().validate(); +ProjectCreateParams params = ProjectCreateParams.builder() + .name("foobar") + .build(); +CompletableFuture project = client.projects().create(params); ``` -### Response properties as JSON +The asynchronous client supports the same options as the synchronous one, except most methods return `CompletableFuture`s. + +## Raw responses + +The SDK defines methods that deserialize responses into instances of Java classes. However, these methods don't provide access to the response headers, status code, or the raw response body. -In rare cases, you may want to access the underlying JSON value for a response property rather than using the typed version provided by -this SDK. Each model property has a corresponding JSON version, with an underscore before the method name, which returns a `JsonField` value. +To access this data, prefix any HTTP method call on a client or service with `withRawResponse()`: ```java -JsonField field = responseObj._field(); +import com.braintrustdata.api.core.http.Headers; +import com.braintrustdata.api.core.http.HttpResponseFor; +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; -if (field.isMissing()) { - // Value was not specified in the JSON response -} else if (field.isNull()) { - // Value was provided as a literal null -} else { - // See if value was provided as a string - Optional jsonString = field.asString(); +ProjectCreateParams params = ProjectCreateParams.builder() + .name("foobar") + .build(); +HttpResponseFor project = client.projects().withRawResponse().create(params); - // If the value given by the API did not match the shape that the SDK expects - // you can deserialise into a custom type - MyClass myObj = responseObj._field().asUnknown().orElseThrow().convert(MyClass.class); -} +int statusCode = project.statusCode(); +Headers headers = project.headers(); ``` -### Additional model properties - -Sometimes, the server response may include additional properties that are not yet available in this library's types. You can access them using the model's `_additionalProperties` method: +You can still deserialize the response into an instance of a Java class if needed: ```java -JsonValue secret = aISecret._additionalProperties().get("secret_field"); +import com.braintrustdata.api.models.Project; + +Project parsedProject = project.parse(); ``` ---- +## Error handling + +The SDK throws custom unchecked exception types: + +- [`BraintrustServiceException`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustServiceException.kt): Base class for HTTP errors. See this table for which exception subclass is thrown for each HTTP status code: + + | Status | Exception | + | ------ | ------------------------------- | + | 400 | `BadRequestException` | + | 401 | `AuthenticationException` | + | 403 | `PermissionDeniedException` | + | 404 | `NotFoundException` | + | 422 | `UnprocessableEntityException` | + | 429 | `RateLimitException` | + | 5xx | `InternalServerException` | + | others | `UnexpectedStatusCodeException` | + +- [`BraintrustIoException`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustIoException.kt): I/O networking errors. + +- [`BraintrustInvalidDataException`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustInvalidDataException.kt): Failure to interpret successfully parsed data. For example, when accessing a property that's supposed to be required, but the API unexpectedly omitted it from the response. + +- [`BraintrustException`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustException.kt): Base class for all exceptions. Most errors will result in one of the previously mentioned ones, but completely generic errors may be thrown using the base class. ## Pagination -For methods that return a paginated list of results, this library provides convenient ways access -the results either one page at a time, or item-by-item across all pages. +For methods that return a paginated list of results, this library provides convenient ways access the results either one page at a time, or item-by-item across all pages. ### Auto-pagination -To iterate through all results across all pages, you can use `autoPager`, -which automatically handles fetching more pages for you: +To iterate through all results across all pages, you can use `autoPager`, which automatically handles fetching more pages for you: ### Synchronous ```java +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectListPage; + // As an Iterable: ProjectListPage page = client.projects().list(params); for (Project project : page.autoPager()) { @@ -197,12 +246,12 @@ asyncClient.projects().list(params).autoPager() ### Manual pagination -If none of the above helpers meet your needs, you can also manually request pages one-by-one. -A page of results has a `data()` method to fetch the list of objects, as well as top-level -`response` and other methods to fetch top-level data about the page. It also has methods -`hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination. +If none of the above helpers meet your needs, you can also manually request pages one-by-one. A page of results has a `data()` method to fetch the list of objects, as well as top-level `response` and other methods to fetch top-level data about the page. It also has methods `hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination. ```java +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectListPage; + ProjectListPage page = client.projects().list(params); while (page != null) { for (Project project : page.objects()) { @@ -213,39 +262,44 @@ while (page != null) { } ``` ---- - -## Error handling +## Logging -This library throws exceptions in a single hierarchy for easy handling: +The SDK uses the standard [OkHttp logging interceptor](https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor). -- **`BraintrustException`** - Base exception for all exceptions +Enable logging by setting the `BRAINTRUST_LOG` environment variable to `info`: - - **`BraintrustServiceException`** - HTTP errors with a well-formed response body we were able to parse. The exception message and the `.debuggingRequestId()` will be set by the server. +```sh +$ export BRAINTRUST_LOG=info +``` - | 400 | BadRequestException | - | ------ | ----------------------------- | - | 401 | AuthenticationException | - | 403 | PermissionDeniedException | - | 404 | NotFoundException | - | 422 | UnprocessableEntityException | - | 429 | RateLimitException | - | 5xx | InternalServerException | - | others | UnexpectedStatusCodeException | +Or to `debug` for more verbose logging: - - **`BraintrustIoException`** - I/O networking errors - - **`BraintrustInvalidDataException`** - any other exceptions on the client side, e.g.: - - We failed to serialize the request body - - We failed to parse the response body (has access to response code and body) +```sh +$ export BRAINTRUST_LOG=debug +``` ## Network options ### Retries -Requests that experience certain errors are automatically retried 2 times by default, with a short exponential backoff. Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, and >=500 Internal errors will all be retried by default. -You can provide a `maxRetries` on the client builder to configure this: +The SDK automatically retries 2 times by default, with a short exponential backoff. + +Only the following error types are retried: + +- Connection errors (for example, due to a network connectivity problem) +- 408 Request Timeout +- 409 Conflict +- 429 Rate Limit +- 5xx Internal + +The API may also explicitly instruct the SDK to retry or not retry a response. + +To set a custom number of retries, configure the client using the `maxRetries` method: ```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; + BraintrustClient client = BraintrustOkHttpClient.builder() .fromEnv() .maxRetries(4) @@ -254,9 +308,26 @@ BraintrustClient client = BraintrustOkHttpClient.builder() ### Timeouts -Requests time out after 1 minute by default. You can configure this on the client builder: +Requests time out after 1 minute by default. + +To set a custom timeout, configure the method call using the `timeout` method: ```java +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; + +Project project = client.projects().create( + params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build() +); +``` + +Or configure the default for all method calls at the client level: + +```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; +import java.time.Duration; + BraintrustClient client = BraintrustOkHttpClient.builder() .fromEnv() .timeout(Duration.ofSeconds(30)) @@ -265,53 +336,238 @@ BraintrustClient client = BraintrustOkHttpClient.builder() ### Proxies -Requests can be routed through a proxy. You can configure this on the client builder: +To route requests through a proxy, configure the client using the `proxy` method: ```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; +import java.net.InetSocketAddress; +import java.net.Proxy; + BraintrustClient client = BraintrustOkHttpClient.builder() .fromEnv() .proxy(new Proxy( - Type.HTTP, - new InetSocketAddress("proxy.com", 8080) + Proxy.Type.HTTP, new InetSocketAddress( + "https://example.com", 8080 + ) )) .build(); ``` -## Making custom/undocumented requests +## Undocumented API functionality -This library is typed for convenient access to the documented API. If you need to access undocumented -params or response properties, the library can still be used. +The SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API. -### Undocumented request params +### Parameters -To make requests using undocumented parameters, you can provide or override parameters on the params object -while building it. +To set undocumented parameters, call the `putAdditionalHeader`, `putAdditionalQueryParam`, or `putAdditionalBodyProperty` methods on any `Params` class: -```kotlin -FooCreateParams address = FooCreateParams.builder() - .id("my_id") - .putAdditionalProperty("secret_prop", JsonValue.from("hello")) +```java +import com.braintrustdata.api.core.JsonValue; +import com.braintrustdata.api.models.ProjectCreateParams; + +ProjectCreateParams params = ProjectCreateParams.builder() + .putAdditionalHeader("Secret-Header", "42") + .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) .build(); ``` -### Undocumented response properties +These can be accessed on the built object later using the `_additionalHeaders()`, `_additionalQueryParams()`, and `_additionalBodyProperties()` methods. + +To set undocumented parameters on _nested_ headers, query params, or body classes, call the `putAdditionalProperty` method on the nested class: + +```java +import com.braintrustdata.api.core.JsonValue; +import com.braintrustdata.api.models.ProjectSettings; +import com.braintrustdata.api.models.ProjectUpdateParams; + +ProjectUpdateParams params = ProjectUpdateParams.builder() + .settings(ProjectSettings.builder() + .putAdditionalProperty("secretProperty", JsonValue.from("42")) + .build()) + .build(); +``` + +These properties can be accessed on the nested built object later using the `_additionalProperties()` method. + +To set a documented parameter or property to an undocumented or not yet supported _value_, pass a [`JsonValue`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt) object to its setter: + +```java +import com.braintrustdata.api.core.JsonValue; +import com.braintrustdata.api.models.ProjectCreateParams; + +ProjectCreateParams params = ProjectCreateParams.builder() + .name(JsonValue.from(42)) + .build(); +``` -To access undocumented response properties, you can use `res._additionalProperties()` on a response object to -get a map of untyped fields of type `Map`. You can then access fields like -`._additionalProperties().get("secret_prop").asString()` or use other helpers defined on the `JsonValue` class -to extract it to a desired type. +The most straightforward way to create a [`JsonValue`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt) is using its `from(...)` method: + +```java +import com.braintrustdata.api.core.JsonValue; +import java.util.List; +import java.util.Map; + +// Create primitive JSON values +JsonValue nullValue = JsonValue.from(null); +JsonValue booleanValue = JsonValue.from(true); +JsonValue numberValue = JsonValue.from(42); +JsonValue stringValue = JsonValue.from("Hello World!"); + +// Create a JSON array value equivalent to `["Hello", "World"]` +JsonValue arrayValue = JsonValue.from(List.of( + "Hello", "World" +)); + +// Create a JSON object value equivalent to `{ "a": 1, "b": 2 }` +JsonValue objectValue = JsonValue.from(Map.of( + "a", 1, + "b", 2 +)); + +// Create an arbitrarily nested JSON equivalent to: +// { +// "a": [1, 2], +// "b": [3, 4] +// } +JsonValue complexValue = JsonValue.from(Map.of( + "a", List.of( + 1, 2 + ), + "b", List.of( + 3, 4 + ) +)); +``` + +### Response properties + +To access undocumented response properties, call the `_additionalProperties()` method: + +```java +import com.braintrustdata.api.core.JsonValue; +import java.util.Map; + +Map additionalProperties = client.projects().create(params)._additionalProperties(); +JsonValue secretPropertyValue = additionalProperties.get("secretProperty"); + +String result = secretPropertyValue.accept(new JsonValue.Visitor<>() { + @Override + public String visitNull() { + return "It's null!"; + } + + @Override + public String visitBoolean(boolean value) { + return "It's a boolean!"; + } + + @Override + public String visitNumber(Number value) { + return "It's a number!"; + } + + // Other methods include `visitMissing`, `visitString`, `visitArray`, and `visitObject` + // The default implementation of each unimplemented method delegates to `visitDefault`, which throws by default, but can also be overridden +}); +``` + +To access a property's raw JSON value, which may be undocumented, call its `_` prefixed method: + +```java +import com.braintrustdata.api.core.JsonField; +import java.util.Optional; + +JsonField name = client.projects().create(params)._name(); + +if (name.isMissing()) { + // The property is absent from the JSON response +} else if (name.isNull()) { + // The property was set to literal null +} else { + // Check if value was provided as a string + // Other methods include `asNumber()`, `asBoolean()`, etc. + Optional jsonString = name.asString(); + + // Try to deserialize into a custom type + MyClass myObject = name.asUnknown().orElseThrow().convert(MyClass.class); +} +``` + +### Response validation + +In rare cases, the API may return a response that doesn't match the expected type. For example, the SDK may expect a property to contain a `String`, but the API could return something else. + +By default, the SDK will not throw an exception in this case. It will throw [`BraintrustInvalidDataException`](braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustInvalidDataException.kt) only if you directly access the property. + +If you would prefer to check that the response is completely well-typed upfront, then either call `validate()`: + +```java +import com.braintrustdata.api.models.Project; + +Project project = client.projects().create(params).validate(); +``` + +Or configure the method call to validate the response using the `responseValidation` method: + +```java +import com.braintrustdata.api.models.Project; +import com.braintrustdata.api.models.ProjectCreateParams; + +Project project = client.projects().create( + params, RequestOptions.builder().responseValidation(true).build() +); +``` + +Or configure the default for all method calls at the client level: + +```java +import com.braintrustdata.api.client.BraintrustClient; +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient; + +BraintrustClient client = BraintrustOkHttpClient.builder() + .fromEnv() + .responseValidation(true) + .build(); +``` + +## FAQ + +### Why don't you use plain `enum` classes? + +Java `enum` classes are not trivially [forwards compatible](https://www.stainless.com/blog/making-java-enums-forwards-compatible). Using them in the SDK could cause runtime exceptions if the API is updated to respond with a new enum value. + +### Why do you represent fields using `JsonField` instead of just plain `T`? + +Using `JsonField` enables a few features: + +- Allowing usage of [undocumented API functionality](#undocumented-api-functionality) +- Lazily [validating the API response against the expected shape](#response-validation) +- Representing absent vs explicitly null values + +### Why don't you use [`data` classes](https://kotlinlang.org/docs/data-classes.html)? + +It is not [backwards compatible to add new fields to a data class](https://kotlinlang.org/docs/api-guidelines-backward-compatibility.html#avoid-using-data-classes-in-your-api) and we don't want to introduce a breaking change every time we add a field to a class. + +### Why don't you use checked exceptions? + +Checked exceptions are widely considered a mistake in the Java programming language. In fact, they were omitted from Kotlin for this reason. + +Checked exceptions: + +- Are verbose to handle +- Encourage error handling at the wrong level of abstraction, where nothing can be done about the error +- Are tedious to propagate due to the [function coloring problem](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function) +- Don't play well with lambdas (also due to the function coloring problem) ## Semantic versioning This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: -1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_. +1. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_ 2. Changes that we do not expect to impact the vast majority of users in practice. We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. We are keen for your feedback; please open an [issue](https://www.github.com/braintrustdata/braintrust-java/issues) with questions, bugs, or suggestions. - -## Requirements - -This library requires Java 8 or later. diff --git a/SECURITY.md b/SECURITY.md index 5702c21d..0923aae0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,9 +2,9 @@ ## Reporting Security Issues -This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. +This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken. -To report a security issue, please contact the Stainless team at security@stainlessapi.com. +To report a security issue, please contact the Stainless team at security@stainless.com. ## Responsible Disclosure @@ -20,7 +20,7 @@ or products provided by Braintrust please follow the respective company's securi ### Braintrust Terms and Policies -Please contact info-test@braintrustdata.com for any questions or concerns regarding security of our services. +Please contact info@braintrustdata.com for any questions or concerns regarding security of our services. --- diff --git a/braintrust-java-client-okhttp/build.gradle.kts b/braintrust-java-client-okhttp/build.gradle.kts index 8c72bdc3..8408ea37 100755 --- a/braintrust-java-client-okhttp/build.gradle.kts +++ b/braintrust-java-client-okhttp/build.gradle.kts @@ -6,10 +6,9 @@ plugins { dependencies { api(project(":braintrust-java-core")) - implementation("com.google.guava:guava:33.0.0-jre") implementation("com.squareup.okhttp3:okhttp:4.12.0") + implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") testImplementation(kotlin("test")) testImplementation("org.assertj:assertj-core:3.25.3") - testImplementation("org.slf4j:slf4j-simple:2.0.12") } diff --git a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClient.kt b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClient.kt index ae986d28..3800c0ed 100755 --- a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClient.kt +++ b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClient.kt @@ -5,26 +5,32 @@ package com.braintrustdata.api.client.okhttp import com.braintrustdata.api.client.BraintrustClient import com.braintrustdata.api.client.BraintrustClientImpl import com.braintrustdata.api.core.ClientOptions +import com.braintrustdata.api.core.Timeout +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.fasterxml.jackson.databind.json.JsonMapper import java.net.Proxy import java.time.Clock import java.time.Duration +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class BraintrustOkHttpClient private constructor() { companion object { + /** Returns a mutable builder for constructing an instance of [BraintrustOkHttpClient]. */ @JvmStatic fun builder() = Builder() @JvmStatic fun fromEnv(): BraintrustClient = builder().fromEnv().build() } - class Builder { + /** A builder for [BraintrustOkHttpClient]. */ + class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var baseUrl: String = ClientOptions.PRODUCTION_URL - // default timeout for client is 1 minute - private var timeout: Duration = Duration.ofSeconds(60) + private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null fun baseUrl(baseUrl: String) = apply { @@ -36,6 +42,8 @@ class BraintrustOkHttpClient private constructor() { fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } + fun headers(headers: Map>) = apply { clientOptions.headers(headers) } @@ -46,13 +54,87 @@ class BraintrustOkHttpClient private constructor() { clientOptions.putHeaders(name, values) } + fun putAllHeaders(headers: Headers) = apply { clientOptions.putAllHeaders(headers) } + fun putAllHeaders(headers: Map>) = apply { clientOptions.putAllHeaders(headers) } - fun removeHeader(name: String) = apply { clientOptions.removeHeader(name) } + fun replaceHeaders(name: String, value: String) = apply { + clientOptions.replaceHeaders(name, value) + } + + fun replaceHeaders(name: String, values: Iterable) = apply { + clientOptions.replaceHeaders(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { clientOptions.replaceAllHeaders(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + clientOptions.replaceAllHeaders(headers) + } + + fun removeHeaders(name: String) = apply { clientOptions.removeHeaders(name) } + + fun removeAllHeaders(names: Set) = apply { clientOptions.removeAllHeaders(names) } + + fun queryParams(queryParams: QueryParams) = apply { clientOptions.queryParams(queryParams) } + + fun queryParams(queryParams: Map>) = apply { + clientOptions.queryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { + clientOptions.putQueryParam(key, value) + } + + fun putQueryParams(key: String, values: Iterable) = apply { + clientOptions.putQueryParams(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + clientOptions.replaceQueryParams(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + clientOptions.replaceQueryParams(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } - fun timeout(timeout: Duration) = apply { this.timeout = timeout } + fun replaceAllQueryParams(queryParams: Map>) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun removeQueryParams(key: String) = apply { clientOptions.removeQueryParams(key) } + + fun removeAllQueryParams(keys: Set) = apply { + clientOptions.removeAllQueryParams(keys) + } + + fun timeout(timeout: Timeout) = apply { + clientOptions.timeout(timeout) + this.timeout = timeout + } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } @@ -64,10 +146,18 @@ class BraintrustOkHttpClient private constructor() { fun apiKey(apiKey: String?) = apply { clientOptions.apiKey(apiKey) } + /** Alias for calling [Builder.apiKey] with `apiKey.orElse(null)`. */ + fun apiKey(apiKey: Optional) = apiKey(apiKey.getOrNull()) + fun fromEnv() = apply { clientOptions.fromEnv() } - fun build(): BraintrustClient { - return BraintrustClientImpl( + /** + * Returns an immutable instance of [BraintrustClient]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BraintrustClient = + BraintrustClientImpl( clientOptions .httpClient( OkHttpClient.builder() @@ -78,6 +168,5 @@ class BraintrustOkHttpClient private constructor() { ) .build() ) - } } } diff --git a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClientAsync.kt b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClientAsync.kt index d813b989..52efdd0a 100755 --- a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClientAsync.kt +++ b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/BraintrustOkHttpClientAsync.kt @@ -5,26 +5,34 @@ package com.braintrustdata.api.client.okhttp import com.braintrustdata.api.client.BraintrustClientAsync import com.braintrustdata.api.client.BraintrustClientAsyncImpl import com.braintrustdata.api.core.ClientOptions +import com.braintrustdata.api.core.Timeout +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.fasterxml.jackson.databind.json.JsonMapper import java.net.Proxy import java.time.Clock import java.time.Duration +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class BraintrustOkHttpClientAsync private constructor() { companion object { + /** + * Returns a mutable builder for constructing an instance of [BraintrustOkHttpClientAsync]. + */ @JvmStatic fun builder() = Builder() @JvmStatic fun fromEnv(): BraintrustClientAsync = builder().fromEnv().build() } - class Builder { + /** A builder for [BraintrustOkHttpClientAsync]. */ + class Builder internal constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var baseUrl: String = ClientOptions.PRODUCTION_URL - // default timeout for client is 1 minute - private var timeout: Duration = Duration.ofSeconds(60) + private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null fun baseUrl(baseUrl: String) = apply { @@ -36,6 +44,8 @@ class BraintrustOkHttpClientAsync private constructor() { fun clock(clock: Clock) = apply { clientOptions.clock(clock) } + fun headers(headers: Headers) = apply { clientOptions.headers(headers) } + fun headers(headers: Map>) = apply { clientOptions.headers(headers) } @@ -46,13 +56,87 @@ class BraintrustOkHttpClientAsync private constructor() { clientOptions.putHeaders(name, values) } + fun putAllHeaders(headers: Headers) = apply { clientOptions.putAllHeaders(headers) } + fun putAllHeaders(headers: Map>) = apply { clientOptions.putAllHeaders(headers) } - fun removeHeader(name: String) = apply { clientOptions.removeHeader(name) } + fun replaceHeaders(name: String, value: String) = apply { + clientOptions.replaceHeaders(name, value) + } + + fun replaceHeaders(name: String, values: Iterable) = apply { + clientOptions.replaceHeaders(name, values) + } + + fun replaceAllHeaders(headers: Headers) = apply { clientOptions.replaceAllHeaders(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + clientOptions.replaceAllHeaders(headers) + } + + fun removeHeaders(name: String) = apply { clientOptions.removeHeaders(name) } + + fun removeAllHeaders(names: Set) = apply { clientOptions.removeAllHeaders(names) } + + fun queryParams(queryParams: QueryParams) = apply { clientOptions.queryParams(queryParams) } + + fun queryParams(queryParams: Map>) = apply { + clientOptions.queryParams(queryParams) + } + + fun putQueryParam(key: String, value: String) = apply { + clientOptions.putQueryParam(key, value) + } + + fun putQueryParams(key: String, values: Iterable) = apply { + clientOptions.putQueryParams(key, values) + } + + fun putAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + clientOptions.putAllQueryParams(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + clientOptions.replaceQueryParams(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + clientOptions.replaceQueryParams(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } - fun timeout(timeout: Duration) = apply { this.timeout = timeout } + fun replaceAllQueryParams(queryParams: Map>) = apply { + clientOptions.replaceAllQueryParams(queryParams) + } + + fun removeQueryParams(key: String) = apply { clientOptions.removeQueryParams(key) } + + fun removeAllQueryParams(keys: Set) = apply { + clientOptions.removeAllQueryParams(keys) + } + + fun timeout(timeout: Timeout) = apply { + clientOptions.timeout(timeout) + this.timeout = timeout + } + + /** + * Sets the maximum time allowed for a complete HTTP call, not including retries. + * + * See [Timeout.request] for more details. + * + * For fine-grained control, pass a [Timeout] object. + */ + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) } @@ -64,10 +148,18 @@ class BraintrustOkHttpClientAsync private constructor() { fun apiKey(apiKey: String?) = apply { clientOptions.apiKey(apiKey) } + /** Alias for calling [Builder.apiKey] with `apiKey.orElse(null)`. */ + fun apiKey(apiKey: Optional) = apiKey(apiKey.getOrNull()) + fun fromEnv() = apply { clientOptions.fromEnv() } - fun build(): BraintrustClientAsync { - return BraintrustClientAsyncImpl( + /** + * Returns an immutable instance of [BraintrustClientAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BraintrustClientAsync = + BraintrustClientAsyncImpl( clientOptions .httpClient( OkHttpClient.builder() @@ -78,6 +170,5 @@ class BraintrustOkHttpClientAsync private constructor() { ) .build() ) - } } } diff --git a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/OkHttpClient.kt b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/OkHttpClient.kt index a7ca15a9..49a5df68 100755 --- a/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/OkHttpClient.kt +++ b/braintrust-java-client-okhttp/src/main/kotlin/com/braintrustdata/api/client/okhttp/OkHttpClient.kt @@ -1,14 +1,15 @@ package com.braintrustdata.api.client.okhttp import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.Timeout +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers import com.braintrustdata.api.core.http.HttpClient import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpRequestBody import com.braintrustdata.api.core.http.HttpResponse import com.braintrustdata.api.errors.BraintrustIoException -import com.google.common.collect.ListMultimap -import com.google.common.collect.MultimapBuilder import java.io.IOException import java.io.InputStream import java.net.Proxy @@ -16,7 +17,6 @@ import java.time.Duration import java.util.concurrent.CompletableFuture import okhttp3.Call import okhttp3.Callback -import okhttp3.Headers import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType @@ -25,28 +25,15 @@ import okhttp3.Request import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response +import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink class OkHttpClient private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val baseUrl: HttpUrl) : HttpClient { - private fun getClient(requestOptions: RequestOptions): okhttp3.OkHttpClient { - val timeout = requestOptions.timeout ?: return okHttpClient - return okHttpClient - .newBuilder() - .connectTimeout(timeout) - .readTimeout(timeout) - .writeTimeout(timeout) - .callTimeout(if (timeout.seconds == 0L) timeout else timeout.plusSeconds(30)) - .build() - } - - override fun execute( - request: HttpRequest, - requestOptions: RequestOptions, - ): HttpResponse { - val call = getClient(requestOptions).newCall(request.toRequest()) + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { + val call = newCall(request, requestOptions) return try { call.execute().toResponse() @@ -65,19 +52,18 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val request.body?.run { future.whenComplete { _, _ -> close() } } - val call = getClient(requestOptions).newCall(request.toRequest()) - - call.enqueue( - object : Callback { - override fun onResponse(call: Call, response: Response) { - future.complete(response.toResponse()) - } + newCall(request, requestOptions) + .enqueue( + object : Callback { + override fun onResponse(call: Call, response: Response) { + future.complete(response.toResponse()) + } - override fun onFailure(call: Call, e: IOException) { - future.completeExceptionally(BraintrustIoException("Request failed", e)) + override fun onFailure(call: Call, e: IOException) { + future.completeExceptionally(BraintrustIoException("Request failed", e)) + } } - } - ) + ) return future } @@ -88,19 +74,71 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val okHttpClient.cache?.close() } - private fun HttpRequest.toRequest(): Request { + private fun newCall(request: HttpRequest, requestOptions: RequestOptions): Call { + val clientBuilder = okHttpClient.newBuilder() + + val logLevel = + when (System.getenv("BRAINTRUST_LOG")?.lowercase()) { + "info" -> HttpLoggingInterceptor.Level.BASIC + "debug" -> HttpLoggingInterceptor.Level.BODY + else -> null + } + if (logLevel != null) { + clientBuilder.addNetworkInterceptor( + HttpLoggingInterceptor().setLevel(logLevel).apply { redactHeader("Authorization") } + ) + } + + requestOptions.timeout?.let { + clientBuilder + .connectTimeout(it.connect()) + .readTimeout(it.read()) + .writeTimeout(it.write()) + .callTimeout(it.request()) + } + + val client = clientBuilder.build() + return client.newCall(request.toRequest(client)) + } + + private fun HttpRequest.toRequest(client: okhttp3.OkHttpClient): Request { var body: RequestBody? = body?.toRequestBody() - // OkHttpClient always requires a request body for PUT and POST methods - if (body == null && (method == HttpMethod.PUT || method == HttpMethod.POST)) { + if (body == null && requiresBody(method)) { body = "".toRequestBody() } val builder = Request.Builder().url(toUrl()).method(method.name, body) - headers.forEach(builder::header) + headers.names().forEach { name -> + headers.values(name).forEach { builder.header(name, it) } + } + + if ( + !headers.names().contains("X-Stainless-Read-Timeout") && client.readTimeoutMillis != 0 + ) { + builder.header( + "X-Stainless-Read-Timeout", + Duration.ofMillis(client.readTimeoutMillis.toLong()).seconds.toString(), + ) + } + if (!headers.names().contains("X-Stainless-Timeout") && client.callTimeoutMillis != 0) { + builder.header( + "X-Stainless-Timeout", + Duration.ofMillis(client.callTimeoutMillis.toLong()).seconds.toString(), + ) + } return builder.build() } + /** `OkHttpClient` always requires a request body for some methods. */ + private fun requiresBody(method: HttpMethod): Boolean = + when (method) { + HttpMethod.POST, + HttpMethod.PUT, + HttpMethod.PATCH -> true + else -> false + } + private fun HttpRequest.toUrl(): String { url?.let { return it @@ -108,7 +146,9 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val val builder = baseUrl.newBuilder() pathSegments.forEach(builder::addPathSegment) - queryParams.forEach(builder::addQueryParameter) + queryParams.keys().forEach { key -> + queryParams.values(key).forEach { builder.addQueryParameter(key, it) } + } return builder.toString() } @@ -118,21 +158,13 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val val length = contentLength() return object : RequestBody() { - override fun contentType(): MediaType? { - return mediaType - } + override fun contentType(): MediaType? = mediaType - override fun contentLength(): Long { - return length - } + override fun contentLength(): Long = length - override fun isOneShot(): Boolean { - return !repeatable() - } + override fun isOneShot(): Boolean = !repeatable() - override fun writeTo(sink: BufferedSink) { - writeTo(sink.outputStream()) - } + override fun writeTo(sink: BufferedSink) = writeTo(sink.outputStream()) } } @@ -140,63 +172,50 @@ private constructor(private val okHttpClient: okhttp3.OkHttpClient, private val val headers = headers.toHeaders() return object : HttpResponse { - override fun statusCode(): Int { - return code - } + override fun statusCode(): Int = code - override fun headers(): ListMultimap { - return headers - } + override fun headers(): Headers = headers - override fun body(): InputStream { - return body!!.byteStream() - } + override fun body(): InputStream = body!!.byteStream() - override fun close() { - body!!.close() - } + override fun close() = body!!.close() } } - private fun Headers.toHeaders(): ListMultimap { - val headers = - MultimapBuilder.treeKeys(String.CASE_INSENSITIVE_ORDER) - .arrayListValues() - .build() - - forEach { pair -> headers.put(pair.first, pair.second) } - - return headers + private fun okhttp3.Headers.toHeaders(): Headers { + val headersBuilder = Headers.builder() + forEach { (name, value) -> headersBuilder.put(name, value) } + return headersBuilder.build() } companion object { @JvmStatic fun builder() = Builder() } - class Builder { + class Builder internal constructor() { private var baseUrl: HttpUrl? = null - // default timeout is 1 minute - private var timeout: Duration = Duration.ofSeconds(60) + private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl.toHttpUrl() } - fun timeout(timeout: Duration) = apply { this.timeout = timeout } + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } - fun build(): OkHttpClient { - return OkHttpClient( + fun build(): OkHttpClient = + OkHttpClient( okhttp3.OkHttpClient.Builder() - .connectTimeout(timeout) - .readTimeout(timeout) - .writeTimeout(timeout) - .callTimeout(if (timeout.seconds == 0L) timeout else timeout.plusSeconds(30)) + .connectTimeout(timeout.connect()) + .readTimeout(timeout.read()) + .writeTimeout(timeout.write()) + .callTimeout(timeout.request()) .proxy(proxy) .build(), - checkNotNull(baseUrl) { "`baseUrl` is required but was not set" }, + checkRequired("baseUrl", baseUrl), ) - } } } diff --git a/braintrust-java-core/build.gradle.kts b/braintrust-java-core/build.gradle.kts index 8688a46e..4d9c5428 100755 --- a/braintrust-java-core/build.gradle.kts +++ b/braintrust-java-core/build.gradle.kts @@ -4,14 +4,14 @@ plugins { } dependencies { - api("com.fasterxml.jackson.core:jackson-core:2.14.3") - api("com.fasterxml.jackson.core:jackson-databind:2.14.3") - api("com.google.guava:guava:33.0.0-jre") + api("com.fasterxml.jackson.core:jackson-core:2.18.1") + api("com.fasterxml.jackson.core:jackson-databind:2.18.1") + api("com.google.errorprone:error_prone_annotations:2.33.0") - implementation("com.fasterxml.jackson.core:jackson-annotations:2.14.3") - implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.3") - implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.3") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.3") + implementation("com.fasterxml.jackson.core:jackson-annotations:2.18.1") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.1") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.1") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.18.1") implementation("org.apache.httpcomponents.core5:httpcore5:5.2.4") implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") @@ -19,8 +19,9 @@ dependencies { testImplementation(project(":braintrust-java-client-okhttp")) testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") testImplementation("org.assertj:assertj-core:3.25.3") - testImplementation("org.assertj:assertj-guava:3.25.3") - testImplementation("org.slf4j:slf4j-simple:2.0.12") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3") + 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") } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClient.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClient.kt index 3424863b..bc327480 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClient.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClient.kt @@ -1,16 +1,56 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.client -import com.braintrustdata.api.models.* -import com.braintrustdata.api.services.blocking.* - +import com.braintrustdata.api.services.blocking.AclService +import com.braintrustdata.api.services.blocking.AiSecretService +import com.braintrustdata.api.services.blocking.ApiKeyService +import com.braintrustdata.api.services.blocking.DatasetService +import com.braintrustdata.api.services.blocking.EnvVarService +import com.braintrustdata.api.services.blocking.EvalService +import com.braintrustdata.api.services.blocking.ExperimentService +import com.braintrustdata.api.services.blocking.FunctionService +import com.braintrustdata.api.services.blocking.GroupService +import com.braintrustdata.api.services.blocking.OrganizationService +import com.braintrustdata.api.services.blocking.ProjectScoreService +import com.braintrustdata.api.services.blocking.ProjectService +import com.braintrustdata.api.services.blocking.ProjectTagService +import com.braintrustdata.api.services.blocking.PromptService +import com.braintrustdata.api.services.blocking.RoleService +import com.braintrustdata.api.services.blocking.SpanIframeService +import com.braintrustdata.api.services.blocking.TopLevelService +import com.braintrustdata.api.services.blocking.UserService +import com.braintrustdata.api.services.blocking.ViewService + +/** + * A client for interacting with the Braintrust REST API synchronously. You can also switch to + * asynchronous execution via the [async] method. + * + * This client performs best when you create a single instance and reuse it for all interactions + * with the REST API. This is because each client holds its own connection pool and thread pools. + * Reusing connections and threads reduces latency and saves memory. The client also handles rate + * limiting per client. This means that creating and using multiple instances at the same time will + * not respect rate limits. + * + * The threads and connections that are held will be released automatically if they remain idle. But + * if you are writing an application that needs to aggressively release unused resources, then you + * may call [close]. + */ interface BraintrustClient { + /** + * Returns a version of this client that uses asynchronous execution. + * + * The returned client shares its resources, like its connection pool and thread pools, with + * this client. + */ fun async(): BraintrustClientAsync + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun topLevel(): TopLevelService fun projects(): ProjectService @@ -33,6 +73,8 @@ interface BraintrustClient { fun projectTags(): ProjectTagService + fun spanIframes(): SpanIframeService + fun functions(): FunctionService fun views(): ViewService @@ -46,4 +88,59 @@ interface BraintrustClient { fun envVars(): EnvVarService fun evals(): EvalService + + /** + * Closes this client, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because the client is long-lived and + * usually should not be synchronously closed via try-with-resources. + * + * It's also usually not necessary to call this method at all. the default HTTP client + * automatically releases threads and connections if they remain idle, but if you are writing an + * application that needs to aggressively release unused resources, then you may call this + * method. + */ + fun close() + + /** A view of [BraintrustClient] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + fun topLevel(): TopLevelService.WithRawResponse + + fun projects(): ProjectService.WithRawResponse + + fun experiments(): ExperimentService.WithRawResponse + + fun datasets(): DatasetService.WithRawResponse + + fun prompts(): PromptService.WithRawResponse + + fun roles(): RoleService.WithRawResponse + + fun groups(): GroupService.WithRawResponse + + fun acls(): AclService.WithRawResponse + + fun users(): UserService.WithRawResponse + + fun projectScores(): ProjectScoreService.WithRawResponse + + fun projectTags(): ProjectTagService.WithRawResponse + + fun spanIframes(): SpanIframeService.WithRawResponse + + fun functions(): FunctionService.WithRawResponse + + fun views(): ViewService.WithRawResponse + + fun organizations(): OrganizationService.WithRawResponse + + fun apiKeys(): ApiKeyService.WithRawResponse + + fun aiSecrets(): AiSecretService.WithRawResponse + + fun envVars(): EnvVarService.WithRawResponse + + fun evals(): EvalService.WithRawResponse + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsync.kt index 94511fd9..24ed3368 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsync.kt @@ -1,16 +1,56 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.client -import com.braintrustdata.api.models.* -import com.braintrustdata.api.services.async.* - +import com.braintrustdata.api.services.async.AclServiceAsync +import com.braintrustdata.api.services.async.AiSecretServiceAsync +import com.braintrustdata.api.services.async.ApiKeyServiceAsync +import com.braintrustdata.api.services.async.DatasetServiceAsync +import com.braintrustdata.api.services.async.EnvVarServiceAsync +import com.braintrustdata.api.services.async.EvalServiceAsync +import com.braintrustdata.api.services.async.ExperimentServiceAsync +import com.braintrustdata.api.services.async.FunctionServiceAsync +import com.braintrustdata.api.services.async.GroupServiceAsync +import com.braintrustdata.api.services.async.OrganizationServiceAsync +import com.braintrustdata.api.services.async.ProjectScoreServiceAsync +import com.braintrustdata.api.services.async.ProjectServiceAsync +import com.braintrustdata.api.services.async.ProjectTagServiceAsync +import com.braintrustdata.api.services.async.PromptServiceAsync +import com.braintrustdata.api.services.async.RoleServiceAsync +import com.braintrustdata.api.services.async.SpanIframeServiceAsync +import com.braintrustdata.api.services.async.TopLevelServiceAsync +import com.braintrustdata.api.services.async.UserServiceAsync +import com.braintrustdata.api.services.async.ViewServiceAsync + +/** + * A client for interacting with the Braintrust REST API asynchronously. You can also switch to + * synchronous execution via the [sync] method. + * + * This client performs best when you create a single instance and reuse it for all interactions + * with the REST API. This is because each client holds its own connection pool and thread pools. + * Reusing connections and threads reduces latency and saves memory. The client also handles rate + * limiting per client. This means that creating and using multiple instances at the same time will + * not respect rate limits. + * + * The threads and connections that are held will be released automatically if they remain idle. But + * if you are writing an application that needs to aggressively release unused resources, then you + * may call [close]. + */ interface BraintrustClientAsync { + /** + * Returns a version of this client that uses synchronous execution. + * + * The returned client shares its resources, like its connection pool and thread pools, with + * this client. + */ fun sync(): BraintrustClient + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun topLevel(): TopLevelServiceAsync fun projects(): ProjectServiceAsync @@ -33,6 +73,8 @@ interface BraintrustClientAsync { fun projectTags(): ProjectTagServiceAsync + fun spanIframes(): SpanIframeServiceAsync + fun functions(): FunctionServiceAsync fun views(): ViewServiceAsync @@ -46,4 +88,61 @@ interface BraintrustClientAsync { fun envVars(): EnvVarServiceAsync fun evals(): EvalServiceAsync + + /** + * Closes this client, relinquishing any underlying resources. + * + * This is purposefully not inherited from [AutoCloseable] because the client is long-lived and + * usually should not be synchronously closed via try-with-resources. + * + * It's also usually not necessary to call this method at all. the default HTTP client + * automatically releases threads and connections if they remain idle, but if you are writing an + * application that needs to aggressively release unused resources, then you may call this + * method. + */ + fun close() + + /** + * A view of [BraintrustClientAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + fun topLevel(): TopLevelServiceAsync.WithRawResponse + + fun projects(): ProjectServiceAsync.WithRawResponse + + fun experiments(): ExperimentServiceAsync.WithRawResponse + + fun datasets(): DatasetServiceAsync.WithRawResponse + + fun prompts(): PromptServiceAsync.WithRawResponse + + fun roles(): RoleServiceAsync.WithRawResponse + + fun groups(): GroupServiceAsync.WithRawResponse + + fun acls(): AclServiceAsync.WithRawResponse + + fun users(): UserServiceAsync.WithRawResponse + + fun projectScores(): ProjectScoreServiceAsync.WithRawResponse + + fun projectTags(): ProjectTagServiceAsync.WithRawResponse + + fun spanIframes(): SpanIframeServiceAsync.WithRawResponse + + fun functions(): FunctionServiceAsync.WithRawResponse + + fun views(): ViewServiceAsync.WithRawResponse + + fun organizations(): OrganizationServiceAsync.WithRawResponse + + fun apiKeys(): ApiKeyServiceAsync.WithRawResponse + + fun aiSecrets(): AiSecretServiceAsync.WithRawResponse + + fun envVars(): EnvVarServiceAsync.WithRawResponse + + fun evals(): EvalServiceAsync.WithRawResponse + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsyncImpl.kt index ee5f3110..e945466b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientAsyncImpl.kt @@ -3,67 +3,133 @@ package com.braintrustdata.api.client import com.braintrustdata.api.core.ClientOptions -import com.braintrustdata.api.core.http.HttpResponse.Handler -import com.braintrustdata.api.errors.BraintrustError -import com.braintrustdata.api.models.* -import com.braintrustdata.api.services.async.* -import com.braintrustdata.api.services.errorHandler - -class BraintrustClientAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : BraintrustClientAsync { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - +import com.braintrustdata.api.core.getPackageVersion +import com.braintrustdata.api.services.async.AclServiceAsync +import com.braintrustdata.api.services.async.AclServiceAsyncImpl +import com.braintrustdata.api.services.async.AiSecretServiceAsync +import com.braintrustdata.api.services.async.AiSecretServiceAsyncImpl +import com.braintrustdata.api.services.async.ApiKeyServiceAsync +import com.braintrustdata.api.services.async.ApiKeyServiceAsyncImpl +import com.braintrustdata.api.services.async.DatasetServiceAsync +import com.braintrustdata.api.services.async.DatasetServiceAsyncImpl +import com.braintrustdata.api.services.async.EnvVarServiceAsync +import com.braintrustdata.api.services.async.EnvVarServiceAsyncImpl +import com.braintrustdata.api.services.async.EvalServiceAsync +import com.braintrustdata.api.services.async.EvalServiceAsyncImpl +import com.braintrustdata.api.services.async.ExperimentServiceAsync +import com.braintrustdata.api.services.async.ExperimentServiceAsyncImpl +import com.braintrustdata.api.services.async.FunctionServiceAsync +import com.braintrustdata.api.services.async.FunctionServiceAsyncImpl +import com.braintrustdata.api.services.async.GroupServiceAsync +import com.braintrustdata.api.services.async.GroupServiceAsyncImpl +import com.braintrustdata.api.services.async.OrganizationServiceAsync +import com.braintrustdata.api.services.async.OrganizationServiceAsyncImpl +import com.braintrustdata.api.services.async.ProjectScoreServiceAsync +import com.braintrustdata.api.services.async.ProjectScoreServiceAsyncImpl +import com.braintrustdata.api.services.async.ProjectServiceAsync +import com.braintrustdata.api.services.async.ProjectServiceAsyncImpl +import com.braintrustdata.api.services.async.ProjectTagServiceAsync +import com.braintrustdata.api.services.async.ProjectTagServiceAsyncImpl +import com.braintrustdata.api.services.async.PromptServiceAsync +import com.braintrustdata.api.services.async.PromptServiceAsyncImpl +import com.braintrustdata.api.services.async.RoleServiceAsync +import com.braintrustdata.api.services.async.RoleServiceAsyncImpl +import com.braintrustdata.api.services.async.SpanIframeServiceAsync +import com.braintrustdata.api.services.async.SpanIframeServiceAsyncImpl +import com.braintrustdata.api.services.async.TopLevelServiceAsync +import com.braintrustdata.api.services.async.TopLevelServiceAsyncImpl +import com.braintrustdata.api.services.async.UserServiceAsync +import com.braintrustdata.api.services.async.UserServiceAsyncImpl +import com.braintrustdata.api.services.async.ViewServiceAsync +import com.braintrustdata.api.services.async.ViewServiceAsyncImpl + +class BraintrustClientAsyncImpl(private val clientOptions: ClientOptions) : BraintrustClientAsync { + + private val clientOptionsWithUserAgent = + if (clientOptions.headers.names().contains("User-Agent")) clientOptions + else + clientOptions + .toBuilder() + .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}") + .build() + + // Pass the original clientOptions so that this client sets its own User-Agent. private val sync: BraintrustClient by lazy { BraintrustClientImpl(clientOptions) } - private val topLevel: TopLevelServiceAsync by lazy { TopLevelServiceAsyncImpl(clientOptions) } + private val withRawResponse: BraintrustClientAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val topLevel: TopLevelServiceAsync by lazy { + TopLevelServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val projects: ProjectServiceAsync by lazy { ProjectServiceAsyncImpl(clientOptions) } + private val projects: ProjectServiceAsync by lazy { + ProjectServiceAsyncImpl(clientOptionsWithUserAgent) + } private val experiments: ExperimentServiceAsync by lazy { - ExperimentServiceAsyncImpl(clientOptions) + ExperimentServiceAsyncImpl(clientOptionsWithUserAgent) } - private val datasets: DatasetServiceAsync by lazy { DatasetServiceAsyncImpl(clientOptions) } + private val datasets: DatasetServiceAsync by lazy { + DatasetServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val prompts: PromptServiceAsync by lazy { PromptServiceAsyncImpl(clientOptions) } + private val prompts: PromptServiceAsync by lazy { + PromptServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val roles: RoleServiceAsync by lazy { RoleServiceAsyncImpl(clientOptions) } + private val roles: RoleServiceAsync by lazy { RoleServiceAsyncImpl(clientOptionsWithUserAgent) } - private val groups: GroupServiceAsync by lazy { GroupServiceAsyncImpl(clientOptions) } + private val groups: GroupServiceAsync by lazy { + GroupServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val acls: AclServiceAsync by lazy { AclServiceAsyncImpl(clientOptions) } + private val acls: AclServiceAsync by lazy { AclServiceAsyncImpl(clientOptionsWithUserAgent) } - private val users: UserServiceAsync by lazy { UserServiceAsyncImpl(clientOptions) } + private val users: UserServiceAsync by lazy { UserServiceAsyncImpl(clientOptionsWithUserAgent) } private val projectScores: ProjectScoreServiceAsync by lazy { - ProjectScoreServiceAsyncImpl(clientOptions) + ProjectScoreServiceAsyncImpl(clientOptionsWithUserAgent) } private val projectTags: ProjectTagServiceAsync by lazy { - ProjectTagServiceAsyncImpl(clientOptions) + ProjectTagServiceAsyncImpl(clientOptionsWithUserAgent) } - private val functions: FunctionServiceAsync by lazy { FunctionServiceAsyncImpl(clientOptions) } + private val spanIframes: SpanIframeServiceAsync by lazy { + SpanIframeServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val views: ViewServiceAsync by lazy { ViewServiceAsyncImpl(clientOptions) } + private val functions: FunctionServiceAsync by lazy { + FunctionServiceAsyncImpl(clientOptionsWithUserAgent) + } + + private val views: ViewServiceAsync by lazy { ViewServiceAsyncImpl(clientOptionsWithUserAgent) } private val organizations: OrganizationServiceAsync by lazy { - OrganizationServiceAsyncImpl(clientOptions) + OrganizationServiceAsyncImpl(clientOptionsWithUserAgent) } - private val apiKeys: ApiKeyServiceAsync by lazy { ApiKeyServiceAsyncImpl(clientOptions) } + private val apiKeys: ApiKeyServiceAsync by lazy { + ApiKeyServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val aiSecrets: AiSecretServiceAsync by lazy { AiSecretServiceAsyncImpl(clientOptions) } + private val aiSecrets: AiSecretServiceAsync by lazy { + AiSecretServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val envVars: EnvVarServiceAsync by lazy { EnvVarServiceAsyncImpl(clientOptions) } + private val envVars: EnvVarServiceAsync by lazy { + EnvVarServiceAsyncImpl(clientOptionsWithUserAgent) + } - private val evals: EvalServiceAsync by lazy { EvalServiceAsyncImpl(clientOptions) } + private val evals: EvalServiceAsync by lazy { EvalServiceAsyncImpl(clientOptionsWithUserAgent) } override fun sync(): BraintrustClient = sync + override fun withRawResponse(): BraintrustClientAsync.WithRawResponse = withRawResponse + override fun topLevel(): TopLevelServiceAsync = topLevel override fun projects(): ProjectServiceAsync = projects @@ -86,6 +152,8 @@ constructor( override fun projectTags(): ProjectTagServiceAsync = projectTags + override fun spanIframes(): SpanIframeServiceAsync = spanIframes + override fun functions(): FunctionServiceAsync = functions override fun views(): ViewServiceAsync = views @@ -99,4 +167,124 @@ constructor( override fun envVars(): EnvVarServiceAsync = envVars override fun evals(): EvalServiceAsync = evals + + override fun close() = clientOptions.httpClient.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + BraintrustClientAsync.WithRawResponse { + + private val topLevel: TopLevelServiceAsync.WithRawResponse by lazy { + TopLevelServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val projects: ProjectServiceAsync.WithRawResponse by lazy { + ProjectServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val experiments: ExperimentServiceAsync.WithRawResponse by lazy { + ExperimentServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val datasets: DatasetServiceAsync.WithRawResponse by lazy { + DatasetServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val prompts: PromptServiceAsync.WithRawResponse by lazy { + PromptServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val roles: RoleServiceAsync.WithRawResponse by lazy { + RoleServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val groups: GroupServiceAsync.WithRawResponse by lazy { + GroupServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val acls: AclServiceAsync.WithRawResponse by lazy { + AclServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val users: UserServiceAsync.WithRawResponse by lazy { + UserServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val projectScores: ProjectScoreServiceAsync.WithRawResponse by lazy { + ProjectScoreServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val projectTags: ProjectTagServiceAsync.WithRawResponse by lazy { + ProjectTagServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val spanIframes: SpanIframeServiceAsync.WithRawResponse by lazy { + SpanIframeServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val functions: FunctionServiceAsync.WithRawResponse by lazy { + FunctionServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val views: ViewServiceAsync.WithRawResponse by lazy { + ViewServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val organizations: OrganizationServiceAsync.WithRawResponse by lazy { + OrganizationServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val apiKeys: ApiKeyServiceAsync.WithRawResponse by lazy { + ApiKeyServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val aiSecrets: AiSecretServiceAsync.WithRawResponse by lazy { + AiSecretServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val envVars: EnvVarServiceAsync.WithRawResponse by lazy { + EnvVarServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val evals: EvalServiceAsync.WithRawResponse by lazy { + EvalServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun topLevel(): TopLevelServiceAsync.WithRawResponse = topLevel + + override fun projects(): ProjectServiceAsync.WithRawResponse = projects + + override fun experiments(): ExperimentServiceAsync.WithRawResponse = experiments + + override fun datasets(): DatasetServiceAsync.WithRawResponse = datasets + + override fun prompts(): PromptServiceAsync.WithRawResponse = prompts + + override fun roles(): RoleServiceAsync.WithRawResponse = roles + + override fun groups(): GroupServiceAsync.WithRawResponse = groups + + override fun acls(): AclServiceAsync.WithRawResponse = acls + + override fun users(): UserServiceAsync.WithRawResponse = users + + override fun projectScores(): ProjectScoreServiceAsync.WithRawResponse = projectScores + + override fun projectTags(): ProjectTagServiceAsync.WithRawResponse = projectTags + + override fun spanIframes(): SpanIframeServiceAsync.WithRawResponse = spanIframes + + override fun functions(): FunctionServiceAsync.WithRawResponse = functions + + override fun views(): ViewServiceAsync.WithRawResponse = views + + override fun organizations(): OrganizationServiceAsync.WithRawResponse = organizations + + override fun apiKeys(): ApiKeyServiceAsync.WithRawResponse = apiKeys + + override fun aiSecrets(): AiSecretServiceAsync.WithRawResponse = aiSecrets + + override fun envVars(): EnvVarServiceAsync.WithRawResponse = envVars + + override fun evals(): EvalServiceAsync.WithRawResponse = evals + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientImpl.kt index e23daeb0..3eecd3cb 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/client/BraintrustClientImpl.kt @@ -3,63 +3,121 @@ package com.braintrustdata.api.client import com.braintrustdata.api.core.ClientOptions -import com.braintrustdata.api.core.http.HttpResponse.Handler -import com.braintrustdata.api.errors.BraintrustError -import com.braintrustdata.api.models.* -import com.braintrustdata.api.services.blocking.* -import com.braintrustdata.api.services.errorHandler - -class BraintrustClientImpl -constructor( - private val clientOptions: ClientOptions, -) : BraintrustClient { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - +import com.braintrustdata.api.core.getPackageVersion +import com.braintrustdata.api.services.blocking.AclService +import com.braintrustdata.api.services.blocking.AclServiceImpl +import com.braintrustdata.api.services.blocking.AiSecretService +import com.braintrustdata.api.services.blocking.AiSecretServiceImpl +import com.braintrustdata.api.services.blocking.ApiKeyService +import com.braintrustdata.api.services.blocking.ApiKeyServiceImpl +import com.braintrustdata.api.services.blocking.DatasetService +import com.braintrustdata.api.services.blocking.DatasetServiceImpl +import com.braintrustdata.api.services.blocking.EnvVarService +import com.braintrustdata.api.services.blocking.EnvVarServiceImpl +import com.braintrustdata.api.services.blocking.EvalService +import com.braintrustdata.api.services.blocking.EvalServiceImpl +import com.braintrustdata.api.services.blocking.ExperimentService +import com.braintrustdata.api.services.blocking.ExperimentServiceImpl +import com.braintrustdata.api.services.blocking.FunctionService +import com.braintrustdata.api.services.blocking.FunctionServiceImpl +import com.braintrustdata.api.services.blocking.GroupService +import com.braintrustdata.api.services.blocking.GroupServiceImpl +import com.braintrustdata.api.services.blocking.OrganizationService +import com.braintrustdata.api.services.blocking.OrganizationServiceImpl +import com.braintrustdata.api.services.blocking.ProjectScoreService +import com.braintrustdata.api.services.blocking.ProjectScoreServiceImpl +import com.braintrustdata.api.services.blocking.ProjectService +import com.braintrustdata.api.services.blocking.ProjectServiceImpl +import com.braintrustdata.api.services.blocking.ProjectTagService +import com.braintrustdata.api.services.blocking.ProjectTagServiceImpl +import com.braintrustdata.api.services.blocking.PromptService +import com.braintrustdata.api.services.blocking.PromptServiceImpl +import com.braintrustdata.api.services.blocking.RoleService +import com.braintrustdata.api.services.blocking.RoleServiceImpl +import com.braintrustdata.api.services.blocking.SpanIframeService +import com.braintrustdata.api.services.blocking.SpanIframeServiceImpl +import com.braintrustdata.api.services.blocking.TopLevelService +import com.braintrustdata.api.services.blocking.TopLevelServiceImpl +import com.braintrustdata.api.services.blocking.UserService +import com.braintrustdata.api.services.blocking.UserServiceImpl +import com.braintrustdata.api.services.blocking.ViewService +import com.braintrustdata.api.services.blocking.ViewServiceImpl + +class BraintrustClientImpl(private val clientOptions: ClientOptions) : BraintrustClient { + + private val clientOptionsWithUserAgent = + if (clientOptions.headers.names().contains("User-Agent")) clientOptions + else + clientOptions + .toBuilder() + .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}") + .build() + + // Pass the original clientOptions so that this client sets its own User-Agent. private val async: BraintrustClientAsync by lazy { BraintrustClientAsyncImpl(clientOptions) } - private val topLevel: TopLevelService by lazy { TopLevelServiceImpl(clientOptions) } + private val withRawResponse: BraintrustClient.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val projects: ProjectService by lazy { ProjectServiceImpl(clientOptions) } + private val topLevel: TopLevelService by lazy { + TopLevelServiceImpl(clientOptionsWithUserAgent) + } + + private val projects: ProjectService by lazy { ProjectServiceImpl(clientOptionsWithUserAgent) } - private val experiments: ExperimentService by lazy { ExperimentServiceImpl(clientOptions) } + private val experiments: ExperimentService by lazy { + ExperimentServiceImpl(clientOptionsWithUserAgent) + } - private val datasets: DatasetService by lazy { DatasetServiceImpl(clientOptions) } + private val datasets: DatasetService by lazy { DatasetServiceImpl(clientOptionsWithUserAgent) } - private val prompts: PromptService by lazy { PromptServiceImpl(clientOptions) } + private val prompts: PromptService by lazy { PromptServiceImpl(clientOptionsWithUserAgent) } - private val roles: RoleService by lazy { RoleServiceImpl(clientOptions) } + private val roles: RoleService by lazy { RoleServiceImpl(clientOptionsWithUserAgent) } - private val groups: GroupService by lazy { GroupServiceImpl(clientOptions) } + private val groups: GroupService by lazy { GroupServiceImpl(clientOptionsWithUserAgent) } - private val acls: AclService by lazy { AclServiceImpl(clientOptions) } + private val acls: AclService by lazy { AclServiceImpl(clientOptionsWithUserAgent) } - private val users: UserService by lazy { UserServiceImpl(clientOptions) } + private val users: UserService by lazy { UserServiceImpl(clientOptionsWithUserAgent) } private val projectScores: ProjectScoreService by lazy { - ProjectScoreServiceImpl(clientOptions) + ProjectScoreServiceImpl(clientOptionsWithUserAgent) } - private val projectTags: ProjectTagService by lazy { ProjectTagServiceImpl(clientOptions) } + private val projectTags: ProjectTagService by lazy { + ProjectTagServiceImpl(clientOptionsWithUserAgent) + } + + private val spanIframes: SpanIframeService by lazy { + SpanIframeServiceImpl(clientOptionsWithUserAgent) + } - private val functions: FunctionService by lazy { FunctionServiceImpl(clientOptions) } + private val functions: FunctionService by lazy { + FunctionServiceImpl(clientOptionsWithUserAgent) + } - private val views: ViewService by lazy { ViewServiceImpl(clientOptions) } + private val views: ViewService by lazy { ViewServiceImpl(clientOptionsWithUserAgent) } private val organizations: OrganizationService by lazy { - OrganizationServiceImpl(clientOptions) + OrganizationServiceImpl(clientOptionsWithUserAgent) } - private val apiKeys: ApiKeyService by lazy { ApiKeyServiceImpl(clientOptions) } + private val apiKeys: ApiKeyService by lazy { ApiKeyServiceImpl(clientOptionsWithUserAgent) } - private val aiSecrets: AiSecretService by lazy { AiSecretServiceImpl(clientOptions) } + private val aiSecrets: AiSecretService by lazy { + AiSecretServiceImpl(clientOptionsWithUserAgent) + } - private val envVars: EnvVarService by lazy { EnvVarServiceImpl(clientOptions) } + private val envVars: EnvVarService by lazy { EnvVarServiceImpl(clientOptionsWithUserAgent) } - private val evals: EvalService by lazy { EvalServiceImpl(clientOptions) } + private val evals: EvalService by lazy { EvalServiceImpl(clientOptionsWithUserAgent) } override fun async(): BraintrustClientAsync = async + override fun withRawResponse(): BraintrustClient.WithRawResponse = withRawResponse + override fun topLevel(): TopLevelService = topLevel override fun projects(): ProjectService = projects @@ -82,6 +140,8 @@ constructor( override fun projectTags(): ProjectTagService = projectTags + override fun spanIframes(): SpanIframeService = spanIframes + override fun functions(): FunctionService = functions override fun views(): ViewService = views @@ -95,4 +155,124 @@ constructor( override fun envVars(): EnvVarService = envVars override fun evals(): EvalService = evals + + override fun close() = clientOptions.httpClient.close() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + BraintrustClient.WithRawResponse { + + private val topLevel: TopLevelService.WithRawResponse by lazy { + TopLevelServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val projects: ProjectService.WithRawResponse by lazy { + ProjectServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val experiments: ExperimentService.WithRawResponse by lazy { + ExperimentServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val datasets: DatasetService.WithRawResponse by lazy { + DatasetServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val prompts: PromptService.WithRawResponse by lazy { + PromptServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val roles: RoleService.WithRawResponse by lazy { + RoleServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val groups: GroupService.WithRawResponse by lazy { + GroupServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val acls: AclService.WithRawResponse by lazy { + AclServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val users: UserService.WithRawResponse by lazy { + UserServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val projectScores: ProjectScoreService.WithRawResponse by lazy { + ProjectScoreServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val projectTags: ProjectTagService.WithRawResponse by lazy { + ProjectTagServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val spanIframes: SpanIframeService.WithRawResponse by lazy { + SpanIframeServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val functions: FunctionService.WithRawResponse by lazy { + FunctionServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val views: ViewService.WithRawResponse by lazy { + ViewServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val organizations: OrganizationService.WithRawResponse by lazy { + OrganizationServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val apiKeys: ApiKeyService.WithRawResponse by lazy { + ApiKeyServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val aiSecrets: AiSecretService.WithRawResponse by lazy { + AiSecretServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val envVars: EnvVarService.WithRawResponse by lazy { + EnvVarServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val evals: EvalService.WithRawResponse by lazy { + EvalServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun topLevel(): TopLevelService.WithRawResponse = topLevel + + override fun projects(): ProjectService.WithRawResponse = projects + + override fun experiments(): ExperimentService.WithRawResponse = experiments + + override fun datasets(): DatasetService.WithRawResponse = datasets + + override fun prompts(): PromptService.WithRawResponse = prompts + + override fun roles(): RoleService.WithRawResponse = roles + + override fun groups(): GroupService.WithRawResponse = groups + + override fun acls(): AclService.WithRawResponse = acls + + override fun users(): UserService.WithRawResponse = users + + override fun projectScores(): ProjectScoreService.WithRawResponse = projectScores + + override fun projectTags(): ProjectTagService.WithRawResponse = projectTags + + override fun spanIframes(): SpanIframeService.WithRawResponse = spanIframes + + override fun functions(): FunctionService.WithRawResponse = functions + + override fun views(): ViewService.WithRawResponse = views + + override fun organizations(): OrganizationService.WithRawResponse = organizations + + override fun apiKeys(): ApiKeyService.WithRawResponse = apiKeys + + override fun aiSecrets(): AiSecretService.WithRawResponse = aiSecrets + + override fun envVars(): EnvVarService.WithRawResponse = envVars + + override fun evals(): EvalService.WithRawResponse = evals + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/BaseDeserializer.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/BaseDeserializer.kt index a38e39bd..64d8a5b3 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/BaseDeserializer.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/BaseDeserializer.kt @@ -18,7 +18,7 @@ abstract class BaseDeserializer(type: KClass) : override fun createContextual( context: DeserializationContext, - property: BeanProperty? + property: BeanProperty?, ): JsonDeserializer { return this } @@ -32,7 +32,7 @@ abstract class BaseDeserializer(type: KClass) : protected fun ObjectCodec.tryDeserialize( node: JsonNode, type: TypeReference, - validate: (T) -> Unit = {} + validate: (T) -> Unit = {}, ): T? { return try { readValue(treeAsTokens(node), type).apply(validate) @@ -46,7 +46,7 @@ abstract class BaseDeserializer(type: KClass) : protected fun ObjectCodec.tryDeserialize( node: JsonNode, type: JavaType, - validate: (T) -> Unit = {} + validate: (T) -> Unit = {}, ): T? { return try { readValue(treeAsTokens(node), type).apply(validate) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Check.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Check.kt new file mode 100644 index 00000000..4a2305ea --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Check.kt @@ -0,0 +1,41 @@ +@file:JvmName("Check") + +package com.braintrustdata.api.core + +fun checkRequired(name: String, value: T?): T = + checkNotNull(value) { "`$name` is required, but was not set" } + +@JvmSynthetic +internal fun checkKnown(name: String, value: JsonField): T = + value.asKnown().orElseThrow { + IllegalStateException("`$name` is not a known type: ${value.javaClass.simpleName}") + } + +@JvmSynthetic +internal fun checkKnown(name: String, value: MultipartField): T = + value.value.asKnown().orElseThrow { + IllegalStateException("`$name` is not a known type: ${value.javaClass.simpleName}") + } + +@JvmSynthetic +internal fun checkLength(name: String, value: String, length: Int): String = + value.also { + check(it.length == length) { "`$name` must have length $length, but was ${it.length}" } + } + +@JvmSynthetic +internal fun checkMinLength(name: String, value: String, minLength: Int): String = + value.also { + check(it.length >= minLength) { + if (minLength == 1) "`$name` must be non-empty, but was empty" + else "`$name` must have at least length $minLength, but was ${it.length}" + } + } + +@JvmSynthetic +internal fun checkMaxLength(name: String, value: String, maxLength: Int): String = + value.also { + check(it.length <= maxLength) { + "`$name` must have at most length $maxLength, but was ${it.length}" + } + } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ClientOptions.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ClientOptions.kt index a63ea9ec..53b6d493 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ClientOptions.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ClientOptions.kt @@ -2,132 +2,233 @@ package com.braintrustdata.api.core +import com.braintrustdata.api.core.http.Headers import com.braintrustdata.api.core.http.HttpClient +import com.braintrustdata.api.core.http.PhantomReachableClosingHttpClient +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.core.http.RetryingHttpClient import com.fasterxml.jackson.databind.json.JsonMapper -import com.google.common.collect.ArrayListMultimap -import com.google.common.collect.ListMultimap import java.time.Clock +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class ClientOptions private constructor( + private val originalHttpClient: HttpClient, @get:JvmName("httpClient") val httpClient: HttpClient, @get:JvmName("jsonMapper") val jsonMapper: JsonMapper, @get:JvmName("clock") val clock: Clock, @get:JvmName("baseUrl") val baseUrl: String, - @get:JvmName("apiKey") val apiKey: String?, - @get:JvmName("headers") val headers: ListMultimap, - @get:JvmName("queryParams") val queryParams: ListMultimap, + @get:JvmName("headers") val headers: Headers, + @get:JvmName("queryParams") val queryParams: QueryParams, @get:JvmName("responseValidation") val responseValidation: Boolean, + @get:JvmName("timeout") val timeout: Timeout, + @get:JvmName("maxRetries") val maxRetries: Int, + private val apiKey: String?, ) { + fun apiKey(): Optional = Optional.ofNullable(apiKey) + + fun toBuilder() = Builder().from(this) + companion object { const val PRODUCTION_URL = "https://api.braintrust.dev" + /** + * Returns a mutable builder for constructing an instance of [ClientOptions]. + * + * The following fields are required: + * ```java + * .httpClient() + * ``` + */ @JvmStatic fun builder() = Builder() @JvmStatic fun fromEnv(): ClientOptions = builder().fromEnv().build() } - class Builder { + /** A builder for [ClientOptions]. */ + class Builder internal constructor() { private var httpClient: HttpClient? = null - private var jsonMapper: JsonMapper? = null + private var jsonMapper: JsonMapper = jsonMapper() private var clock: Clock = Clock.systemUTC() private var baseUrl: String = PRODUCTION_URL - private var headers: MutableMap> = mutableMapOf() - private var queryParams: MutableMap> = mutableMapOf() + private var headers: Headers.Builder = Headers.builder() + private var queryParams: QueryParams.Builder = QueryParams.builder() private var responseValidation: Boolean = false + private var timeout: Timeout = Timeout.default() private var maxRetries: Int = 2 private var apiKey: String? = null + @JvmSynthetic + internal fun from(clientOptions: ClientOptions) = apply { + httpClient = clientOptions.originalHttpClient + jsonMapper = clientOptions.jsonMapper + clock = clientOptions.clock + baseUrl = clientOptions.baseUrl + headers = clientOptions.headers.toBuilder() + queryParams = clientOptions.queryParams.toBuilder() + responseValidation = clientOptions.responseValidation + timeout = clientOptions.timeout + maxRetries = clientOptions.maxRetries + apiKey = clientOptions.apiKey + } + fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient } fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper } + fun clock(clock: Clock) = apply { this.clock = clock } + fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl } - fun clock(clock: Clock) = apply { this.clock = clock } + fun responseValidation(responseValidation: Boolean) = apply { + this.responseValidation = responseValidation + } + + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } + + fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } + + fun apiKey(apiKey: String?) = apply { this.apiKey = apiKey } + + /** Alias for calling [Builder.apiKey] with `apiKey.orElse(null)`. */ + fun apiKey(apiKey: Optional) = apiKey(apiKey.getOrNull()) + + fun headers(headers: Headers) = apply { + this.headers.clear() + putAllHeaders(headers) + } fun headers(headers: Map>) = apply { this.headers.clear() putAllHeaders(headers) } - fun putHeader(name: String, value: String) = apply { - this.headers.getOrPut(name) { mutableListOf() }.add(value) + fun putHeader(name: String, value: String) = apply { headers.put(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { headers.put(name, values) } + + fun putAllHeaders(headers: Headers) = apply { this.headers.putAll(headers) } + + fun putAllHeaders(headers: Map>) = apply { + this.headers.putAll(headers) } - fun putHeaders(name: String, values: Iterable) = apply { - this.headers.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceHeaders(name: String, value: String) = apply { headers.replace(name, value) } + + fun replaceHeaders(name: String, values: Iterable) = apply { + headers.replace(name, values) } - fun putAllHeaders(headers: Map>) = apply { - headers.forEach(this::putHeaders) + fun replaceAllHeaders(headers: Headers) = apply { this.headers.replaceAll(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + this.headers.replaceAll(headers) } - fun removeHeader(name: String) = apply { this.headers.put(name, mutableListOf()) } + fun removeHeaders(name: String) = apply { headers.remove(name) } + + fun removeAllHeaders(names: Set) = apply { headers.removeAll(names) } + + fun queryParams(queryParams: QueryParams) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) + } fun queryParams(queryParams: Map>) = apply { this.queryParams.clear() putAllQueryParams(queryParams) } - fun putQueryParam(name: String, value: String) = apply { - this.queryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putQueryParam(key: String, value: String) = apply { queryParams.put(key, value) } + + fun putQueryParams(key: String, values: Iterable) = apply { + queryParams.put(key, values) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.queryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.putAll(queryParams) } fun putAllQueryParams(queryParams: Map>) = apply { - queryParams.forEach(this::putQueryParams) + this.queryParams.putAll(queryParams) } - fun removeQueryParam(name: String) = apply { this.queryParams.put(name, mutableListOf()) } + fun replaceQueryParams(key: String, value: String) = apply { + queryParams.replace(key, value) + } - fun responseValidation(responseValidation: Boolean) = apply { - this.responseValidation = responseValidation + fun replaceQueryParams(key: String, values: Iterable) = apply { + queryParams.replace(key, values) } - fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries } + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.replaceAll(queryParams) + } - fun apiKey(apiKey: String?) = apply { this.apiKey = apiKey } + fun replaceAllQueryParams(queryParams: Map>) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun removeQueryParams(key: String) = apply { queryParams.remove(key) } + + fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) } fun fromEnv() = apply { System.getenv("BRAINTRUST_API_KEY")?.let { apiKey(it) } } + /** + * Returns an immutable instance of [ClientOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .httpClient() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ClientOptions { - checkNotNull(httpClient) { "`httpClient` is required but was not set" } + val httpClient = checkRequired("httpClient", httpClient) - val headers = ArrayListMultimap.create() - val queryParams = ArrayListMultimap.create() + val headers = Headers.builder() + val queryParams = QueryParams.builder() headers.put("X-Stainless-Lang", "java") headers.put("X-Stainless-Arch", getOsArch()) headers.put("X-Stainless-OS", getOsName()) headers.put("X-Stainless-OS-Version", getOsVersion()) headers.put("X-Stainless-Package-Version", getPackageVersion()) + headers.put("X-Stainless-Runtime", "JRE") headers.put("X-Stainless-Runtime-Version", getJavaVersion()) - if (!apiKey.isNullOrEmpty()) { - headers.put("Authorization", "Bearer ${apiKey}") + apiKey?.let { + if (!it.isEmpty()) { + headers.put("Authorization", "Bearer $it") + } } - this.headers.forEach(headers::replaceValues) - this.queryParams.forEach(queryParams::replaceValues) + headers.replaceAll(this.headers.build()) + queryParams.replaceAll(this.queryParams.build()) return ClientOptions( - RetryingHttpClient.builder() - .httpClient(httpClient!!) - .clock(clock) - .maxRetries(maxRetries) - .build(), - jsonMapper ?: jsonMapper(), + httpClient, + PhantomReachableClosingHttpClient( + RetryingHttpClient.builder() + .httpClient(httpClient) + .clock(clock) + .maxRetries(maxRetries) + .build() + ), + jsonMapper, clock, baseUrl, - apiKey, - headers.toUnmodifiable(), - queryParams.toUnmodifiable(), + headers.build(), + queryParams.build(), responseValidation, + timeout, + maxRetries, + apiKey, ) } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ObjectMappers.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ObjectMappers.kt index 5b1f8ea1..588027c6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ObjectMappers.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/ObjectMappers.kt @@ -2,20 +2,29 @@ package com.braintrustdata.api.core +import com.braintrustdata.api.errors.BraintrustException +import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.SerializationFeature +import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.cfg.CoercionAction.Fail import com.fasterxml.jackson.databind.cfg.CoercionInputShape.Integer +import com.fasterxml.jackson.databind.exc.InvalidDefinitionException +import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.datatype.jdk8.Jdk8Module import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder +import java.io.InputStream fun jsonMapper(): JsonMapper = jacksonMapperBuilder() .addModule(Jdk8Module()) .addModule(JavaTimeModule()) + .addModule(SimpleModule().addSerializer(InputStreamJsonSerializer)) .serializationInclusion(JsonInclude.Include.NON_ABSENT) .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) .disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE) @@ -23,3 +32,53 @@ fun jsonMapper(): JsonMapper = .disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS) .withCoercionConfig(String::class.java) { it.setCoercion(Integer, Fail) } .build() + +private object InputStreamJsonSerializer : BaseSerializer(InputStream::class) { + + override fun serialize( + value: InputStream?, + gen: JsonGenerator?, + serializers: SerializerProvider?, + ) { + if (value == null) { + gen?.writeNull() + } else { + value.use { gen?.writeBinary(it.readBytes()) } + } + } +} + +@JvmSynthetic +internal fun enhanceJacksonException(fallbackMessage: String, e: Exception): Exception { + // These exceptions should only happen if our code is wrong OR if the user is using a binary + // incompatible version of `com.fasterxml.jackson.core:jackson-databind`: + // https://javadoc.io/static/com.fasterxml.jackson.core/jackson-databind/2.18.1/index.html + val isUnexpectedException = + e is UnrecognizedPropertyException || e is InvalidDefinitionException + if (!isUnexpectedException) { + return BraintrustInvalidDataException(fallbackMessage, e) + } + + val jacksonVersion = JsonMapper::class.java.`package`.implementationVersion + if (jacksonVersion.isNullOrEmpty() || jacksonVersion == COMPILED_JACKSON_VERSION) { + return BraintrustInvalidDataException(fallbackMessage, e) + } + + return BraintrustException( + """ + Jackson threw an unexpected exception and its runtime version ($jacksonVersion) mismatches the version the SDK was compiled with ($COMPILED_JACKSON_VERSION). + + You may be using a version of `com.fasterxml.jackson.core:jackson-databind` that's not binary compatible with the SDK. + + This can happen if you are either: + 1. Directly depending on a different Jackson version + 2. Depending on some library that depends on a different Jackson version, potentially transitively + + Double-check that you are depending on a compatible Jackson version. + """ + .trimIndent(), + e, + ) +} + +const val COMPILED_JACKSON_VERSION = "2.18.1" diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Params.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Params.kt new file mode 100644 index 00000000..f98bf142 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Params.kt @@ -0,0 +1,16 @@ +package com.braintrustdata.api.core + +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams + +/** An interface representing parameters passed to a service method. */ +interface Params { + /** The full set of headers in the parameters, including both fixed and additional headers. */ + fun _headers(): Headers + + /** + * The full set of query params in the parameters, including both fixed and additional query + * params. + */ + fun _queryParams(): QueryParams +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PhantomReachable.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PhantomReachable.kt new file mode 100644 index 00000000..91785b1a --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PhantomReachable.kt @@ -0,0 +1,56 @@ +@file:JvmName("PhantomReachable") + +package com.braintrustdata.api.core + +import com.braintrustdata.api.errors.BraintrustException +import java.lang.reflect.InvocationTargetException + +/** + * Closes [closeable] when [observed] becomes only phantom reachable. + * + * This is a wrapper around a Java 9+ [java.lang.ref.Cleaner], or a no-op in older Java versions. + */ +@JvmSynthetic +internal fun closeWhenPhantomReachable(observed: Any, closeable: AutoCloseable) { + check(observed !== closeable) { + "`observed` cannot be the same object as `closeable` because it would never become phantom reachable" + } + closeWhenPhantomReachable(observed, closeable::close) +} + +/** + * Calls [close] when [observed] becomes only phantom reachable. + * + * This is a wrapper around a Java 9+ [java.lang.ref.Cleaner], or a no-op in older Java versions. + */ +@JvmSynthetic +internal fun closeWhenPhantomReachable(observed: Any, close: () -> Unit) { + closeWhenPhantomReachable?.let { it(observed, close) } +} + +private val closeWhenPhantomReachable: ((Any, () -> Unit) -> Unit)? by lazy { + try { + val cleanerClass = Class.forName("java.lang.ref.Cleaner") + val cleanerCreate = cleanerClass.getMethod("create") + val cleanerRegister = + cleanerClass.getMethod("register", Any::class.java, Runnable::class.java) + val cleanerObject = cleanerCreate.invoke(null); + + { observed, close -> + try { + cleanerRegister.invoke(cleanerObject, observed, Runnable { close() }) + } catch (e: ReflectiveOperationException) { + if (e is InvocationTargetException) { + when (val cause = e.cause) { + is RuntimeException, + is Error -> throw cause + } + } + throw BraintrustException("Unexpected reflective invocation failure", e) + } + } + } catch (e: ReflectiveOperationException) { + // We're running Java 8, which has no Cleaner. + null + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PrepareRequest.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PrepareRequest.kt new file mode 100644 index 00000000..e9aaadff --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/PrepareRequest.kt @@ -0,0 +1,24 @@ +@file:JvmName("PrepareRequest") + +package com.braintrustdata.api.core + +import com.braintrustdata.api.core.http.HttpRequest +import java.util.concurrent.CompletableFuture + +@JvmSynthetic +internal fun HttpRequest.prepare(clientOptions: ClientOptions, params: Params): HttpRequest = + toBuilder() + .putAllQueryParams(clientOptions.queryParams) + .replaceAllQueryParams(params._queryParams()) + .putAllHeaders(clientOptions.headers) + .replaceAllHeaders(params._headers()) + .build() + +@JvmSynthetic +internal fun HttpRequest.prepareAsync( + clientOptions: ClientOptions, + params: Params, +): CompletableFuture = + // This async version exists to make it easier to add async specific preparation logic in the + // future. + CompletableFuture.completedFuture(prepare(clientOptions, params)) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Properties.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Properties.kt index 1c59eee1..a0924603 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Properties.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Properties.kt @@ -34,14 +34,9 @@ fun getOsName(): String { } } -fun getOsVersion(): String { - return System.getProperty("os.version", "unknown") -} +fun getOsVersion(): String = System.getProperty("os.version", "unknown") -fun getPackageVersion(): String { - return Properties::class.java.`package`.implementationVersion ?: "unknown" -} +fun getPackageVersion(): String = + Properties::class.java.`package`.implementationVersion ?: "unknown" -fun getJavaVersion(): String { - return System.getProperty("java.version", "unknown") -} +fun getJavaVersion(): String = System.getProperty("java.version", "unknown") diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/RequestOptions.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/RequestOptions.kt index 7a8c8b26..fe7c8372 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/RequestOptions.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/RequestOptions.kt @@ -2,17 +2,7 @@ package com.braintrustdata.api.core import java.time.Duration -class RequestOptions -private constructor( - val responseValidation: Boolean?, - val timeout: Duration?, -) { - fun applyDefaults(options: RequestOptions): RequestOptions { - return RequestOptions( - responseValidation = this.responseValidation ?: options.responseValidation, - timeout = this.timeout ?: options.timeout, - ) - } +class RequestOptions private constructor(val responseValidation: Boolean?, val timeout: Timeout?) { companion object { @@ -20,21 +10,37 @@ private constructor( @JvmStatic fun none() = NONE + @JvmSynthetic + internal fun from(clientOptions: ClientOptions): RequestOptions = + builder() + .responseValidation(clientOptions.responseValidation) + .timeout(clientOptions.timeout) + .build() + @JvmStatic fun builder() = Builder() } - class Builder { + fun applyDefaults(options: RequestOptions): RequestOptions = + RequestOptions( + responseValidation = responseValidation ?: options.responseValidation, + timeout = + if (options.timeout != null && timeout != null) timeout.assign(options.timeout) + else timeout ?: options.timeout, + ) + + class Builder internal constructor() { + private var responseValidation: Boolean? = null - private var timeout: Duration? = null + private var timeout: Timeout? = null fun responseValidation(responseValidation: Boolean) = apply { this.responseValidation = responseValidation } - fun timeout(timeout: Duration) = apply { this.timeout = timeout } + fun timeout(timeout: Timeout) = apply { this.timeout = timeout } - fun build(): RequestOptions { - return RequestOptions(responseValidation, timeout) - } + fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build()) + + fun build(): RequestOptions = RequestOptions(responseValidation, timeout) } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Timeout.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Timeout.kt new file mode 100644 index 00000000..06ee42fa --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Timeout.kt @@ -0,0 +1,167 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.core + +import java.time.Duration +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A class containing timeouts for various processing phases of a request. */ +class Timeout +private constructor( + private val connect: Duration?, + private val read: Duration?, + private val write: Duration?, + private val request: Duration?, +) { + + /** + * The maximum time allowed to establish a connection with a host. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun connect(): Duration = connect ?: Duration.ofMinutes(1) + + /** + * The maximum time allowed between two data packets when waiting for the server’s response. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun read(): Duration = read ?: request() + + /** + * The maximum time allowed between two data packets when sending the request to the server. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun write(): Duration = write ?: request() + + /** + * The maximum time allowed for a complete HTTP call, not including retries. + * + * This includes resolving DNS, connecting, writing the request body, server processing, as well + * as reading the response body. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun request(): Duration = request ?: Duration.ofMinutes(1) + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun default() = builder().build() + + /** Returns a mutable builder for constructing an instance of [Timeout]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Timeout]. */ + class Builder internal constructor() { + + private var connect: Duration? = null + private var read: Duration? = null + private var write: Duration? = null + private var request: Duration? = null + + @JvmSynthetic + internal fun from(timeout: Timeout) = apply { + connect = timeout.connect + read = timeout.read + write = timeout.write + request = timeout.request + } + + /** + * The maximum time allowed to establish a connection with a host. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun connect(connect: Duration?) = apply { this.connect = connect } + + /** Alias for calling [Builder.connect] with `connect.orElse(null)`. */ + fun connect(connect: Optional) = connect(connect.getOrNull()) + + /** + * The maximum time allowed between two data packets when waiting for the server’s response. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun read(read: Duration?) = apply { this.read = read } + + /** Alias for calling [Builder.read] with `read.orElse(null)`. */ + fun read(read: Optional) = read(read.getOrNull()) + + /** + * The maximum time allowed between two data packets when sending the request to the server. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `request()`. + */ + fun write(write: Duration?) = apply { this.write = write } + + /** Alias for calling [Builder.write] with `write.orElse(null)`. */ + fun write(write: Optional) = write(write.getOrNull()) + + /** + * The maximum time allowed for a complete HTTP call, not including retries. + * + * This includes resolving DNS, connecting, writing the request body, server processing, as + * well as reading the response body. + * + * A value of [Duration.ZERO] means there's no timeout. + * + * Defaults to `Duration.ofMinutes(1)`. + */ + fun request(request: Duration?) = apply { this.request = request } + + /** Alias for calling [Builder.request] with `request.orElse(null)`. */ + fun request(request: Optional) = request(request.getOrNull()) + + /** + * Returns an immutable instance of [Timeout]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Timeout = Timeout(connect, read, write, request) + } + + @JvmSynthetic + internal fun assign(target: Timeout): Timeout = + target + .toBuilder() + .apply { + connect?.let(this::connect) + read?.let(this::read) + write?.let(this::write) + request?.let(this::request) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Timeout && connect == other.connect && read == other.read && write == other.write && request == other.request /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(connect, read, write, request) /* spotless:on */ + + override fun toString() = + "Timeout{connect=$connect, read=$read, write=$write, request=$request}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Utils.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Utils.kt index dd23bef7..6761ce6a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Utils.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Utils.kt @@ -3,59 +3,62 @@ package com.braintrustdata.api.core import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.google.common.collect.ImmutableListMultimap -import com.google.common.collect.ListMultimap -import com.google.common.collect.Multimaps import java.util.Collections +import java.util.SortedMap @JvmSynthetic -internal fun T?.getOrThrow(name: String): T { - if (this == null) { - throw BraintrustInvalidDataException("'${name}' is not present") - } +internal fun T?.getOrThrow(name: String): T = + this ?: throw BraintrustInvalidDataException("`${name}` is not present") - return this -} +@JvmSynthetic +internal fun List.toImmutable(): List = + if (isEmpty()) Collections.emptyList() else Collections.unmodifiableList(toList()) @JvmSynthetic -internal fun List.toUnmodifiable(): List { - if (isEmpty()) { - return Collections.emptyList() - } +internal fun Map.toImmutable(): Map = + if (isEmpty()) immutableEmptyMap() else Collections.unmodifiableMap(toMap()) - return Collections.unmodifiableList(this) -} +@JvmSynthetic internal fun immutableEmptyMap(): Map = Collections.emptyMap() @JvmSynthetic -internal fun Map.toUnmodifiable(): Map { - if (isEmpty()) { - return Collections.emptyMap() - } - - return Collections.unmodifiableMap(this) -} +internal fun , V> SortedMap.toImmutable(): SortedMap = + if (isEmpty()) Collections.emptySortedMap() + else Collections.unmodifiableSortedMap(toSortedMap(comparator())) +/** + * Returns whether [this] is equal to [other]. + * + * This differs from [Object.equals] because it also deeply equates arrays based on their contents, + * even when there are arrays directly nested within other arrays. + */ @JvmSynthetic -internal fun ListMultimap.toUnmodifiable(): ListMultimap { - if (isEmpty()) { - return ImmutableListMultimap.of() - } +internal infix fun Any?.contentEquals(other: Any?): Boolean = + arrayOf(this).contentDeepEquals(arrayOf(other)) - return Multimaps.unmodifiableListMultimap(this) -} +/** + * Returns a hash of the given sequence of [values]. + * + * This differs from [java.util.Objects.hash] because it also deeply hashes arrays based on their + * contents, even when there are arrays directly nested within other arrays. + */ +@JvmSynthetic internal fun contentHash(vararg values: Any?): Int = values.contentDeepHashCode() +/** + * Returns a [String] representation of [this]. + * + * This differs from [Object.toString] because it also deeply stringifies arrays based on their + * contents, even when there are arrays directly nested within other arrays. + */ @JvmSynthetic -internal fun ListMultimap.getRequiredHeader(header: String): String { - val value = - entries() - .stream() - .filter { entry -> entry.key.equals(header, ignoreCase = true) } - .map { entry -> entry.value } - .findFirst() - if (!value.isPresent) { - throw BraintrustInvalidDataException("Could not find $header header") +internal fun Any?.contentToString(): String { + var string = arrayOf(this).contentDeepToString() + if (string.startsWith('[')) { + string = string.substring(1) + } + if (string.endsWith(']')) { + string = string.substring(0, string.length - 1) } - return value.get() + return string } internal interface Enum diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt index 9ede4db6..c25a05d5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/Values.kt @@ -27,10 +27,9 @@ import com.fasterxml.jackson.databind.node.JsonNodeType.OBJECT import com.fasterxml.jackson.databind.node.JsonNodeType.POJO import com.fasterxml.jackson.databind.node.JsonNodeType.STRING import com.fasterxml.jackson.databind.ser.std.NullSerializer -import java.nio.charset.Charset +import java.io.InputStream import java.util.Objects import java.util.Optional -import org.apache.hc.core5.http.ContentType @JsonDeserialize(using = JsonField.Deserializer::class) sealed class JsonField { @@ -59,36 +58,69 @@ sealed class JsonField { fun asBoolean(): Optional = when (this) { is JsonBoolean -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? Boolean) else -> Optional.empty() } fun asNumber(): Optional = when (this) { is JsonNumber -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? Number) else -> Optional.empty() } fun asString(): Optional = when (this) { is JsonString -> Optional.of(value) + is KnownValue -> Optional.ofNullable(value as? String) else -> Optional.empty() } fun asStringOrThrow(): String = - when (this) { - is JsonString -> value - else -> throw BraintrustInvalidDataException("Value is not a string") - } + asString().orElseThrow { BraintrustInvalidDataException("Value is not a string") } fun asArray(): Optional> = when (this) { is JsonArray -> Optional.of(values) + is KnownValue -> + Optional.ofNullable( + (value as? List<*>)?.map { + try { + JsonValue.from(it) + } catch (e: IllegalArgumentException) { + // The known value is a list, but not all values are convertible to + // `JsonValue`. + return Optional.empty() + } + } + ) else -> Optional.empty() } fun asObject(): Optional> = when (this) { is JsonObject -> Optional.of(values) + is KnownValue -> + Optional.ofNullable( + (value as? Map<*, *>) + ?.map { (key, value) -> + if (key !is String) { + return Optional.empty() + } + + val jsonValue = + try { + JsonValue.from(value) + } catch (e: IllegalArgumentException) { + // The known value is a map, but not all items are convertible + // to `JsonValue`. + return Optional.empty() + } + + key to jsonValue + } + ?.toMap() + ) else -> Optional.empty() } @@ -96,9 +128,9 @@ sealed class JsonField { internal fun getRequired(name: String): T = when (this) { is KnownValue -> value - is JsonMissing -> throw BraintrustInvalidDataException("'${name}' is not set") - is JsonNull -> throw BraintrustInvalidDataException("'${name}' is null") - else -> throw BraintrustInvalidDataException("'${name}' is invalid, received ${this}") + is JsonMissing -> throw BraintrustInvalidDataException("`$name` is not set") + is JsonNull -> throw BraintrustInvalidDataException("`$name` is null") + else -> throw BraintrustInvalidDataException("`$name` is invalid, received $this") } @JvmSynthetic @@ -107,7 +139,7 @@ sealed class JsonField { is KnownValue -> value is JsonMissing -> null is JsonNull -> null - else -> throw BraintrustInvalidDataException("'${name}' is invalid, received ${this}") + else -> throw BraintrustInvalidDataException("`$name` is invalid, received $this") } @JvmSynthetic @@ -117,6 +149,8 @@ sealed class JsonField { is JsonValue -> this } + @JvmSynthetic fun accept(consume: (T) -> Unit) = asKnown().ifPresent(consume) + fun accept(visitor: Visitor): R = when (this) { is KnownValue -> visitor.visitKnown(value) @@ -138,10 +172,15 @@ sealed class JsonField { } } - // This class is a Jackson filter that can be used to exclude missing properties from objects - // This filter should not be used directly and should instead use the @ExcludeMissing annotation + /** + * This class is a Jackson filter that can be used to exclude missing properties from objects. + * This filter should not be used directly and should instead use the @ExcludeMissing + * annotation. + */ class IsMissing { override fun equals(other: Any?): Boolean = other is JsonMissing + + override fun hashCode(): Int = Objects.hash() } class Deserializer(private val type: JavaType? = null) : @@ -150,18 +189,13 @@ sealed class JsonField { override fun createContextual( context: DeserializationContext, property: BeanProperty?, - ): JsonDeserializer> { - return Deserializer(context.contextualType?.containedType(0)) - } + ): JsonDeserializer> = Deserializer(context.contextualType?.containedType(0)) - override fun ObjectCodec.deserialize(node: JsonNode): JsonField<*> { - return type?.let { tryDeserialize(node, type) }?.let { of(it) } + override fun ObjectCodec.deserialize(node: JsonNode): JsonField<*> = + type?.let { tryDeserialize(node, type) }?.let { of(it) } ?: JsonValue.fromJsonNode(node) - } - override fun getNullValue(context: DeserializationContext): JsonField<*> { - return JsonNull.of() - } + override fun getNullValue(context: DeserializationContext): JsonField<*> = JsonNull.of() } } @@ -236,13 +270,9 @@ sealed class JsonValue : JsonField() { } class Deserializer : BaseDeserializer(JsonValue::class) { - override fun ObjectCodec.deserialize(node: JsonNode): JsonValue { - return fromJsonNode(node) - } + override fun ObjectCodec.deserialize(node: JsonNode): JsonValue = fromJsonNode(node) - override fun getNullValue(context: DeserializationContext?): JsonValue { - return JsonNull.of() - } + override fun getNullValue(context: DeserializationContext?): JsonValue = JsonNull.of() } } @@ -256,12 +286,12 @@ private constructor( return true } - return other is KnownValue<*> && value == other.value + return other is KnownValue<*> && value contentEquals other.value } - override fun hashCode() = value.hashCode() + override fun hashCode() = contentHash(value) - override fun toString() = value.toString() + override fun toString() = value.contentToString() companion object { @JsonCreator @JvmStatic fun of(value: T) = KnownValue(value) @@ -283,7 +313,7 @@ class JsonMissing : JsonValue() { override fun serialize( value: JsonMissing, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { throw RuntimeException("JsonMissing cannot be serialized") } @@ -387,7 +417,7 @@ private constructor( override fun toString() = values.toString() companion object { - @JsonCreator @JvmStatic fun of(values: List) = JsonArray(values.toUnmodifiable()) + @JsonCreator @JvmStatic fun of(values: List) = JsonArray(values.toImmutable()) } } @@ -413,15 +443,12 @@ private constructor( companion object { @JsonCreator @JvmStatic - fun of(values: Map) = JsonObject(values.toUnmodifiable()) + fun of(values: Map) = JsonObject(values.toImmutable()) } } @JacksonAnnotationsInside -@JsonInclude( - JsonInclude.Include.CUSTOM, - valueFilter = JsonField.IsMissing::class, -) +@JsonInclude(JsonInclude.Include.CUSTOM, valueFilter = JsonField.IsMissing::class) annotation class ExcludeMissing @JacksonAnnotationsInside @@ -430,106 +457,84 @@ annotation class ExcludeMissing isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, creatorVisibility = Visibility.NONE, - fieldVisibility = Visibility.NONE + fieldVisibility = Visibility.NONE, ) annotation class NoAutoDetect -class MultipartFormValue -internal constructor( - val name: String, - val value: T, - val contentType: ContentType, - val filename: String? = null +class MultipartField +private constructor( + @get:JvmName("value") val value: JsonField, + @get:JvmName("contentType") val contentType: String, + private val filename: String?, ) { - private var hashCode: Int = 0 - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - contentType, - filename, - when (value) { - is ByteArray -> value.contentHashCode() - is String -> value - is Boolean -> value - is Long -> value - is Double -> value - else -> value?.hashCode() - } - ) - } - return hashCode + companion object { + + @JvmStatic fun of(value: T?) = builder().value(value).build() + + @JvmStatic fun of(value: JsonField) = builder().value(value).build() + + @JvmStatic fun builder() = Builder() } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other == null || this.javaClass != other.javaClass) return false + fun filename(): Optional = Optional.ofNullable(filename) + + @JvmSynthetic + internal fun map(transform: (T) -> R): MultipartField = + MultipartField.builder() + .value(value.map(transform)) + .contentType(contentType) + .filename(filename) + .build() + + /** A builder for [MultipartField]. */ + class Builder internal constructor() { + + private var value: JsonField? = null + private var contentType: String? = null + private var filename: String? = null + + fun value(value: JsonField) = apply { this.value = value } - other as MultipartFormValue<*> + fun value(value: T?) = value(JsonField.ofNullable(value)) - if (name != other.name || contentType != other.contentType || filename != other.filename) - return false + fun contentType(contentType: String) = apply { this.contentType = contentType } - return when { - value is ByteArray && other.value is ByteArray -> value contentEquals other.value - else -> value?.equals(other.value) ?: (other.value == null) + fun filename(filename: String?) = apply { this.filename = filename } + + fun filename(filename: Optional) = filename(filename.orElse(null)) + + fun build(): MultipartField { + val value = checkRequired("value", value) + return MultipartField( + value, + contentType + ?: if ( + value is KnownValue && + (value.value is InputStream || value.value is ByteArray) + ) + "application/octet-stream" + else "text/plain; charset=utf-8", + filename, + ) } } - override fun toString(): String { - return "MultipartFormValue(name='$name', contentType=$contentType, filename=$filename, value=${valueToString()})" - } + private val hashCode: Int by lazy { contentHash(value, contentType, filename) } + + override fun hashCode(): Int = hashCode - private fun valueToString(): String = - when (value) { - is ByteArray -> "ByteArray of size ${value.size}" - else -> value.toString() + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - companion object { - internal fun fromString( - name: String, - value: String, - contentType: ContentType - ): MultipartFormValue = MultipartFormValue(name, value, contentType) - - internal fun fromBoolean( - name: String, - value: Boolean, - contentType: ContentType, - ): MultipartFormValue = MultipartFormValue(name, value, contentType) - - internal fun fromLong( - name: String, - value: Long, - contentType: ContentType, - ): MultipartFormValue = MultipartFormValue(name, value, contentType) - - internal fun fromDouble( - name: String, - value: Double, - contentType: ContentType, - ): MultipartFormValue = MultipartFormValue(name, value, contentType) - - internal fun fromEnum( - name: String, - value: T, - contentType: ContentType - ): MultipartFormValue = MultipartFormValue(name, value, contentType) - - internal fun fromByteArray( - name: String, - value: ByteArray, - contentType: ContentType, - filename: String? = null - ): MultipartFormValue = MultipartFormValue(name, value, contentType, filename) + return other is MultipartField<*> && + value == other.value && + contentType == other.contentType && + filename == other.filename } -} -internal object ContentTypes { - val DefaultText = ContentType.create(ContentType.TEXT_PLAIN.mimeType, Charset.forName("UTF-8")) - val DefaultBinary = ContentType.DEFAULT_BINARY + override fun toString(): String = + "MultipartField{value=$value, contentType=$contentType, filename=$filename}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/Handlers.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/ErrorHandler.kt old mode 100755 new mode 100644 similarity index 56% rename from braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/Handlers.kt rename to braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/ErrorHandler.kt index 8ac9e3df..12cfc384 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/Handlers.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/ErrorHandler.kt @@ -1,13 +1,12 @@ -@file:JvmName("Handlers") +@file:JvmName("ErrorHandler") -package com.braintrustdata.api.services +package com.braintrustdata.api.core.handlers -import com.braintrustdata.api.core.http.BinaryResponseContent +import com.braintrustdata.api.core.http.Headers import com.braintrustdata.api.core.http.HttpResponse import com.braintrustdata.api.core.http.HttpResponse.Handler import com.braintrustdata.api.errors.BadRequestException import com.braintrustdata.api.errors.BraintrustError -import com.braintrustdata.api.errors.BraintrustException import com.braintrustdata.api.errors.InternalServerException import com.braintrustdata.api.errors.NotFoundException import com.braintrustdata.api.errors.PermissionDeniedException @@ -16,77 +15,26 @@ import com.braintrustdata.api.errors.UnauthorizedException import com.braintrustdata.api.errors.UnexpectedStatusCodeException import com.braintrustdata.api.errors.UnprocessableEntityException import com.fasterxml.jackson.databind.json.JsonMapper -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import com.google.common.collect.ListMultimap import java.io.ByteArrayInputStream import java.io.InputStream -import java.io.OutputStream -import java.util.Optional - -@JvmSynthetic internal fun emptyHandler(): Handler = EmptyHandler - -private object EmptyHandler : Handler { - override fun handle(response: HttpResponse): Void? = null -} - -@JvmSynthetic internal fun stringHandler(): Handler = StringHandler - -@JvmSynthetic internal fun binaryHandler(): Handler = BinaryHandler - -private object StringHandler : Handler { - override fun handle(response: HttpResponse): String { - return response.body().readBytes().toString(Charsets.UTF_8) - } -} - -private object BinaryHandler : Handler { - override fun handle(response: HttpResponse): BinaryResponseContent { - return object : BinaryResponseContent { - override fun contentType(): Optional = - Optional.ofNullable(response.headers().get("Content-Type").firstOrNull()) - - override fun body(): InputStream = response.body() - - override fun close() = response.close() - - override fun writeTo(outputStream: OutputStream) { - response.body().copyTo(outputStream) - } - } - } -} - -@JvmSynthetic -internal inline fun jsonHandler(jsonMapper: JsonMapper): Handler { - return object : Handler { - override fun handle(response: HttpResponse): T { - try { - return jsonMapper.readValue(response.body(), jacksonTypeRef()) - } catch (e: Exception) { - throw BraintrustException("Error reading response", e) - } - } - } -} @JvmSynthetic internal fun errorHandler(jsonMapper: JsonMapper): Handler { val handler = jsonHandler(jsonMapper) return object : Handler { - override fun handle(response: HttpResponse): BraintrustError { + override fun handle(response: HttpResponse): BraintrustError = try { - return handler.handle(response) + handler.handle(response) } catch (e: Exception) { - return BraintrustError.builder().build() + BraintrustError.builder().build() } - } } } @JvmSynthetic -internal fun Handler.withErrorHandler(errorHandler: Handler): Handler { - return object : Handler { +internal fun Handler.withErrorHandler(errorHandler: Handler): Handler = + object : Handler { override fun handle(response: HttpResponse): T { when (val statusCode = response.statusCode()) { in 200..299 -> { @@ -96,7 +44,7 @@ internal fun Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler Handler.withErrorHandler(errorHandler: Handler { - return this@buffered.headers() - } + override fun headers(): Headers = this@buffered.headers() - override fun body(): InputStream { - return ByteArrayInputStream(body) - } + override fun body(): InputStream = ByteArrayInputStream(body) - override fun close() { - this@buffered.close() - } + override fun close() = this@buffered.close() } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/JsonHandler.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/JsonHandler.kt new file mode 100644 index 00000000..ae855a7b --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/JsonHandler.kt @@ -0,0 +1,20 @@ +@file:JvmName("JsonHandler") + +package com.braintrustdata.api.core.handlers + +import com.braintrustdata.api.core.enhanceJacksonException +import com.braintrustdata.api.core.http.HttpResponse +import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef + +@JvmSynthetic +internal inline fun jsonHandler(jsonMapper: JsonMapper): Handler = + object : Handler { + override fun handle(response: HttpResponse): T = + try { + jsonMapper.readValue(response.body(), jacksonTypeRef()) + } catch (e: Exception) { + throw enhanceJacksonException("Error reading response", e) + } + } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/StringHandler.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/StringHandler.kt new file mode 100644 index 00000000..bb04609d --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/handlers/StringHandler.kt @@ -0,0 +1,13 @@ +@file:JvmName("StringHandler") + +package com.braintrustdata.api.core.handlers + +import com.braintrustdata.api.core.http.HttpResponse +import com.braintrustdata.api.core.http.HttpResponse.Handler + +@JvmSynthetic internal fun stringHandler(): Handler = StringHandlerInternal + +private object StringHandlerInternal : Handler { + override fun handle(response: HttpResponse): String = + response.body().readBytes().toString(Charsets.UTF_8) +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/BinaryResponseContent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/BinaryResponseContent.kt deleted file mode 100755 index c10ab40f..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/BinaryResponseContent.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.braintrustdata.api.core.http - -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.lang.AutoCloseable -import java.util.Optional - -interface BinaryResponseContent : AutoCloseable { - - fun contentType(): Optional - - fun body(): InputStream - - @Throws(IOException::class) fun writeTo(outputStream: OutputStream) -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/Headers.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/Headers.kt new file mode 100644 index 00000000..6d37e804 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/Headers.kt @@ -0,0 +1,92 @@ +package com.braintrustdata.api.core.http + +import com.braintrustdata.api.core.toImmutable +import java.util.TreeMap + +class Headers +private constructor( + private val map: Map>, + @get:JvmName("size") val size: Int, +) { + + fun isEmpty(): Boolean = map.isEmpty() + + fun names(): Set = map.keys + + fun values(name: String): List = map[name].orEmpty() + + fun toBuilder(): Builder = Builder().putAll(map) + + companion object { + + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private val map: MutableMap> = + TreeMap(String.CASE_INSENSITIVE_ORDER) + private var size: Int = 0 + + fun put(name: String, value: String) = apply { + map.getOrPut(name) { mutableListOf() }.add(value) + size++ + } + + fun put(name: String, values: Iterable) = apply { values.forEach { put(name, it) } } + + fun putAll(headers: Map>) = apply { headers.forEach(::put) } + + fun putAll(headers: Headers) = apply { + headers.names().forEach { put(it, headers.values(it)) } + } + + fun remove(name: String) = apply { size -= map.remove(name).orEmpty().size } + + fun removeAll(names: Set) = apply { names.forEach(::remove) } + + fun clear() = apply { + map.clear() + size = 0 + } + + fun replace(name: String, value: String) = apply { + remove(name) + put(name, value) + } + + fun replace(name: String, values: Iterable) = apply { + remove(name) + put(name, values) + } + + fun replaceAll(headers: Map>) = apply { + headers.forEach(::replace) + } + + fun replaceAll(headers: Headers) = apply { + headers.names().forEach { replace(it, headers.values(it)) } + } + + fun build() = + Headers( + map.mapValuesTo(TreeMap(String.CASE_INSENSITIVE_ORDER)) { (_, values) -> + values.toImmutable() + } + .toImmutable(), + size, + ) + } + + override fun hashCode(): Int = map.hashCode() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Headers && map == other.map + } + + override fun toString(): String = "Headers{map=$map}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpClient.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpClient.kt index f4163046..5941bacd 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpClient.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpClient.kt @@ -11,8 +11,16 @@ interface HttpClient : AutoCloseable { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponse + fun execute(request: HttpRequest): HttpResponse = execute(request, RequestOptions.none()) + fun executeAsync( request: HttpRequest, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + fun executeAsync(request: HttpRequest): CompletableFuture = + executeAsync(request, RequestOptions.none()) + + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequest.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequest.kt index f4ba383e..1105f7d4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequest.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequest.kt @@ -1,91 +1,145 @@ package com.braintrustdata.api.core.http -import com.braintrustdata.api.core.toUnmodifiable -import com.google.common.collect.ArrayListMultimap -import com.google.common.collect.ListMultimap -import com.google.common.collect.Multimap -import com.google.common.collect.MultimapBuilder +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.toImmutable class HttpRequest private constructor( @get:JvmName("method") val method: HttpMethod, @get:JvmName("url") val url: String?, @get:JvmName("pathSegments") val pathSegments: List, - @get:JvmName("queryParams") val queryParams: ListMultimap, - @get:JvmName("headers") val headers: ListMultimap, + @get:JvmName("headers") val headers: Headers, + @get:JvmName("queryParams") val queryParams: QueryParams, @get:JvmName("body") val body: HttpRequestBody?, ) { + fun toBuilder(): Builder = Builder().from(this) + override fun toString(): String = - "HttpRequest {method=$method, pathSegments=$pathSegments, queryParams=$queryParams, headers=$headers, body=$body}" + "HttpRequest{method=$method, url=$url, pathSegments=$pathSegments, headers=$headers, queryParams=$queryParams, body=$body}" companion object { @JvmStatic fun builder() = Builder() } - class Builder { + class Builder internal constructor() { private var method: HttpMethod? = null private var url: String? = null - private var pathSegments: MutableList = ArrayList() - private var queryParams: ListMultimap = ArrayListMultimap.create() + private var pathSegments: MutableList = mutableListOf() + private var headers: Headers.Builder = Headers.builder() + private var queryParams: QueryParams.Builder = QueryParams.builder() private var body: HttpRequestBody? = null - private var headers: ListMultimap = - MultimapBuilder.treeKeys(String.CASE_INSENSITIVE_ORDER).arrayListValues().build() + + @JvmSynthetic + internal fun from(request: HttpRequest) = apply { + method = request.method + url = request.url + pathSegments = request.pathSegments.toMutableList() + headers = request.headers.toBuilder() + queryParams = request.queryParams.toBuilder() + body = request.body + } fun method(method: HttpMethod) = apply { this.method = method } fun url(url: String) = apply { this.url = url } - fun addPathSegment(pathSegment: String) = apply { this.pathSegments.add(pathSegment) } + fun addPathSegment(pathSegment: String) = apply { pathSegments.add(pathSegment) } fun addPathSegments(vararg pathSegments: String) = apply { - for (pathSegment in pathSegments) { - this.pathSegments.add(pathSegment) - } + this.pathSegments.addAll(pathSegments) } - fun putQueryParam(name: String, value: String) = apply { - this.queryParams.replaceValues(name, listOf(value)) + fun headers(headers: Headers) = apply { + this.headers.clear() + putAllHeaders(headers) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.queryParams.replaceValues(name, values) + fun headers(headers: Map>) = apply { + this.headers.clear() + putAllHeaders(headers) } - fun putAllQueryParams(queryParams: Map>) = apply { - queryParams.forEach(this::putQueryParams) + fun putHeader(name: String, value: String) = apply { headers.put(name, value) } + + fun putHeaders(name: String, values: Iterable) = apply { headers.put(name, values) } + + fun putAllHeaders(headers: Headers) = apply { this.headers.putAll(headers) } + + fun putAllHeaders(headers: Map>) = apply { + this.headers.putAll(headers) } - fun putAllQueryParams(queryParams: Multimap) = apply { - queryParams.asMap().forEach(this::putQueryParams) + fun replaceHeaders(name: String, value: String) = apply { headers.replace(name, value) } + + fun replaceHeaders(name: String, values: Iterable) = apply { + headers.replace(name, values) } - fun putHeader(name: String, value: String) = apply { - this.headers.replaceValues(name, listOf(value)) + fun replaceAllHeaders(headers: Headers) = apply { this.headers.replaceAll(headers) } + + fun replaceAllHeaders(headers: Map>) = apply { + this.headers.replaceAll(headers) } - fun putHeaders(name: String, values: Iterable) = apply { - this.headers.replaceValues(name, values) + fun removeHeaders(name: String) = apply { headers.remove(name) } + + fun removeAllHeaders(names: Set) = apply { headers.removeAll(names) } + + fun queryParams(queryParams: QueryParams) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) } - fun putAllHeaders(headers: Map>) = apply { - headers.forEach(this::putHeaders) + fun queryParams(queryParams: Map>) = apply { + this.queryParams.clear() + putAllQueryParams(queryParams) } - fun putAllHeaders(headers: Multimap) = apply { - headers.asMap().forEach(this::putHeaders) + fun putQueryParam(key: String, value: String) = apply { queryParams.put(key, value) } + + fun putQueryParams(key: String, values: Iterable) = apply { + queryParams.put(key, values) } + fun putAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.putAll(queryParams) + } + + fun putAllQueryParams(queryParams: Map>) = apply { + this.queryParams.putAll(queryParams) + } + + fun replaceQueryParams(key: String, value: String) = apply { + queryParams.replace(key, value) + } + + fun replaceQueryParams(key: String, values: Iterable) = apply { + queryParams.replace(key, values) + } + + fun replaceAllQueryParams(queryParams: QueryParams) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun replaceAllQueryParams(queryParams: Map>) = apply { + this.queryParams.replaceAll(queryParams) + } + + fun removeQueryParams(key: String) = apply { queryParams.remove(key) } + + fun removeAllQueryParams(keys: Set) = apply { queryParams.removeAll(keys) } + fun body(body: HttpRequestBody) = apply { this.body = body } fun build(): HttpRequest = HttpRequest( - checkNotNull(method) { "`method` is required but was not set" }, + checkRequired("method", method), url, - pathSegments.toUnmodifiable(), - queryParams.toUnmodifiable(), - headers, + pathSegments.toImmutable(), + headers.build(), + queryParams.build(), body, ) } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBodies.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBodies.kt new file mode 100644 index 00000000..bb5b61ab --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBodies.kt @@ -0,0 +1,131 @@ +// File generated from our OpenAPI spec by Stainless. + +@file:JvmName("HttpRequestBodies") + +package com.braintrustdata.api.core.http + +import com.braintrustdata.api.core.MultipartField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.databind.node.JsonNodeType +import java.io.ByteArrayInputStream +import java.io.InputStream +import java.io.OutputStream +import kotlin.jvm.optionals.getOrNull +import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder +import org.apache.hc.core5.http.ContentType +import org.apache.hc.core5.http.HttpEntity + +@JvmSynthetic +internal inline fun json(jsonMapper: JsonMapper, value: T): HttpRequestBody = + object : HttpRequestBody { + private val bytes: ByteArray by lazy { jsonMapper.writeValueAsBytes(value) } + + override fun writeTo(outputStream: OutputStream) = outputStream.write(bytes) + + override fun contentType(): String = "application/json" + + override fun contentLength(): Long = bytes.size.toLong() + + override fun repeatable(): Boolean = true + + override fun close() {} + } + +@JvmSynthetic +internal fun multipartFormData( + jsonMapper: JsonMapper, + fields: Map>, +): HttpRequestBody = + object : HttpRequestBody { + private val entity: HttpEntity by lazy { + MultipartEntityBuilder.create() + .apply { + fields.forEach { (name, field) -> + val knownValue = field.value.asKnown().getOrNull() + val parts = + if (knownValue is InputStream) { + // Read directly from the `InputStream` instead of reading it all + // into memory due to the `jsonMapper` serialization below. + sequenceOf(name to knownValue) + } else { + val node = jsonMapper.valueToTree(field.value) + serializePart(name, node) + } + + parts.forEach { (name, bytes) -> + addBinaryBody( + name, + bytes, + ContentType.parseLenient(field.contentType), + field.filename().getOrNull(), + ) + } + } + } + .build() + } + + private fun serializePart( + name: String, + node: JsonNode, + ): Sequence> = + when (node.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> emptySequence() + JsonNodeType.BINARY -> sequenceOf(name to ByteArrayInputStream(node.binaryValue())) + JsonNodeType.STRING -> sequenceOf(name to node.textValue().toInputStream()) + JsonNodeType.BOOLEAN -> + sequenceOf(name to node.booleanValue().toString().toInputStream()) + JsonNodeType.NUMBER -> + sequenceOf(name to node.numberValue().toString().toInputStream()) + JsonNodeType.ARRAY -> + sequenceOf( + name to + node + .elements() + .asSequence() + .mapNotNull { element -> + when (element.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> null + JsonNodeType.STRING -> node.textValue() + JsonNodeType.BOOLEAN -> node.booleanValue().toString() + JsonNodeType.NUMBER -> node.numberValue().toString() + null, + JsonNodeType.BINARY, + JsonNodeType.ARRAY, + JsonNodeType.OBJECT, + JsonNodeType.POJO -> + throw BraintrustInvalidDataException( + "Unexpected JsonNode type in array: ${node.nodeType}" + ) + } + } + .joinToString(",") + .toInputStream() + ) + JsonNodeType.OBJECT -> + node.fields().asSequence().flatMap { (key, value) -> + serializePart("$name[$key]", value) + } + JsonNodeType.POJO, + null -> + throw BraintrustInvalidDataException( + "Unexpected JsonNode type: ${node.nodeType}" + ) + } + + private fun String.toInputStream(): InputStream = ByteArrayInputStream(toByteArray()) + + override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream) + + override fun contentType(): String = entity.contentType + + override fun contentLength(): Long = entity.contentLength + + override fun repeatable(): Boolean = entity.isRepeatable + + override fun close() = entity.close() + } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBody.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBody.kt index e5c7df37..ebf2b4d5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBody.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpRequestBody.kt @@ -1,12 +1,11 @@ package com.braintrustdata.api.core.http -import java.io.IOException import java.io.OutputStream import java.lang.AutoCloseable interface HttpRequestBody : AutoCloseable { - @Throws(IOException::class) fun writeTo(outputStream: OutputStream) + fun writeTo(outputStream: OutputStream) fun contentType(): String? @@ -21,5 +20,6 @@ interface HttpRequestBody : AutoCloseable { */ fun repeatable(): Boolean + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ override fun close() } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponse.kt index 333dda67..901b030b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponse.kt @@ -1,6 +1,5 @@ package com.braintrustdata.api.core.http -import com.google.common.collect.ListMultimap import java.io.InputStream import java.lang.AutoCloseable @@ -8,10 +7,13 @@ interface HttpResponse : AutoCloseable { fun statusCode(): Int - fun headers(): ListMultimap + fun headers(): Headers fun body(): InputStream + /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */ + override fun close() + interface Handler { fun handle(response: HttpResponse): T diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponseFor.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponseFor.kt new file mode 100644 index 00000000..6cb31fa8 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/HttpResponseFor.kt @@ -0,0 +1,23 @@ +package com.braintrustdata.api.core.http + +import java.io.InputStream + +interface HttpResponseFor : HttpResponse { + + fun parse(): T +} + +@JvmSynthetic +internal fun HttpResponse.parseable(parse: () -> T): HttpResponseFor = + object : HttpResponseFor { + + override fun parse(): T = parse() + + override fun statusCode(): Int = this@parseable.statusCode() + + override fun headers(): Headers = this@parseable.headers() + + override fun body(): InputStream = this@parseable.body() + + override fun close() = this@parseable.close() + } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/PhantomReachableClosingHttpClient.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/PhantomReachableClosingHttpClient.kt new file mode 100644 index 00000000..e766e040 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/PhantomReachableClosingHttpClient.kt @@ -0,0 +1,26 @@ +package com.braintrustdata.api.core.http + +import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.closeWhenPhantomReachable +import java.util.concurrent.CompletableFuture + +/** + * A delegating wrapper around an `HttpClient` that closes it once it's only phantom reachable. + * + * This class ensures the `HttpClient` is closed even if the user forgets to close it. + */ +internal class PhantomReachableClosingHttpClient(private val httpClient: HttpClient) : HttpClient { + init { + closeWhenPhantomReachable(this, httpClient) + } + + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse = + httpClient.execute(request, requestOptions) + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = httpClient.executeAsync(request, requestOptions) + + override fun close() = httpClient.close() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/QueryParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/QueryParams.kt new file mode 100644 index 00000000..03c719df --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/QueryParams.kt @@ -0,0 +1,88 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.core.http + +import com.braintrustdata.api.core.toImmutable + +class QueryParams +private constructor( + private val map: Map>, + @get:JvmName("size") val size: Int, +) { + + fun isEmpty(): Boolean = map.isEmpty() + + fun keys(): Set = map.keys + + fun values(key: String): List = map[key].orEmpty() + + fun toBuilder(): Builder = Builder().putAll(map) + + companion object { + + @JvmStatic fun builder() = Builder() + } + + class Builder internal constructor() { + + private val map: MutableMap> = mutableMapOf() + private var size: Int = 0 + + fun put(key: String, value: String) = apply { + map.getOrPut(key) { mutableListOf() }.add(value) + size++ + } + + fun put(key: String, values: Iterable) = apply { values.forEach { put(key, it) } } + + fun putAll(queryParams: Map>) = apply { + queryParams.forEach(::put) + } + + fun putAll(queryParams: QueryParams) = apply { + queryParams.keys().forEach { put(it, queryParams.values(it)) } + } + + fun replace(key: String, value: String) = apply { + remove(key) + put(key, value) + } + + fun replace(key: String, values: Iterable) = apply { + remove(key) + put(key, values) + } + + fun replaceAll(queryParams: Map>) = apply { + queryParams.forEach(::replace) + } + + fun replaceAll(queryParams: QueryParams) = apply { + queryParams.keys().forEach { replace(it, queryParams.values(it)) } + } + + fun remove(key: String) = apply { size -= map.remove(key).orEmpty().size } + + fun removeAll(keys: Set) = apply { keys.forEach(::remove) } + + fun clear() = apply { + map.clear() + size = 0 + } + + fun build() = + QueryParams(map.mapValues { (_, values) -> values.toImmutable() }.toImmutable(), size) + } + + override fun hashCode(): Int = map.hashCode() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is QueryParams && map == other.map + } + + override fun toString(): String = "QueryParams{map=$map}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/RetryingHttpClient.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/RetryingHttpClient.kt index 450eb8af..56bdac87 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/RetryingHttpClient.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/core/http/RetryingHttpClient.kt @@ -1,10 +1,8 @@ -@file:JvmSynthetic - package com.braintrustdata.api.core.http import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.errors.BraintrustIoException -import com.google.common.util.concurrent.MoreExecutors import java.io.IOException import java.time.Clock import java.time.Duration @@ -30,43 +28,43 @@ private constructor( private val idempotencyHeader: String?, ) : HttpClient { - override fun execute( - request: HttpRequest, - requestOptions: RequestOptions, - ): HttpResponse { + override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { if (!isRetryable(request) || maxRetries <= 0) { return httpClient.execute(request, requestOptions) } - maybeAddIdempotencyHeader(request) + var modifiedRequest = maybeAddIdempotencyHeader(request) // Don't send the current retry count in the headers if the caller set their own value. - val shouldSendRetryCount = !request.headers.containsKey("x-stainless-retry-count") + val shouldSendRetryCount = + !modifiedRequest.headers.names().contains("X-Stainless-Retry-Count") var retries = 0 while (true) { if (shouldSendRetryCount) { - setRetryCountHeader(request, retries) + modifiedRequest = setRetryCountHeader(modifiedRequest, retries) } val response = try { - val response = httpClient.execute(request, requestOptions) + val response = httpClient.execute(modifiedRequest, requestOptions) if (++retries > maxRetries || !shouldRetry(response)) { return response } response - } catch (t: Throwable) { - if (++retries > maxRetries || !shouldRetry(t)) { - throw t + } catch (throwable: Throwable) { + if (++retries > maxRetries || !shouldRetry(throwable)) { + throw throwable } null } val backoffMillis = getRetryBackoffMillis(retries, response) + // All responses must be closed, so close the failed one before retrying. + response?.close() Thread.sleep(backoffMillis.toMillis()) } } @@ -79,10 +77,11 @@ private constructor( return httpClient.executeAsync(request, requestOptions) } - maybeAddIdempotencyHeader(request) + val modifiedRequest = maybeAddIdempotencyHeader(request) // Don't send the current retry count in the headers if the caller set their own value. - val shouldSendRetryCount = !request.headers.containsKey("x-stainless-retry-count") + val shouldSendRetryCount = + !modifiedRequest.headers.names().contains("X-Stainless-Retry-Count") var retries = 0 @@ -90,16 +89,15 @@ private constructor( request: HttpRequest, requestOptions: RequestOptions, ): CompletableFuture { - if (shouldSendRetryCount) { - setRetryCountHeader(request, retries) - } + val requestWithRetryCount = + if (shouldSendRetryCount) setRetryCountHeader(request, retries) else request return httpClient - .executeAsync(request, requestOptions) + .executeAsync(requestWithRetryCount, requestOptions) .handleAsync( fun( response: HttpResponse?, - throwable: Throwable? + throwable: Throwable?, ): CompletableFuture { if (response != null) { if (++retries > maxRetries || !shouldRetry(response)) { @@ -114,45 +112,49 @@ private constructor( } val backoffMillis = getRetryBackoffMillis(retries, response) + // All responses must be closed, so close the failed one before retrying. + response?.close() return sleepAsync(backoffMillis.toMillis()).thenCompose { - executeWithRetries(request, requestOptions) + executeWithRetries(requestWithRetryCount, requestOptions) } - }, - MoreExecutors.directExecutor() - ) + } + ) { + // Run in the same thread. + it.run() + } .thenCompose(Function.identity()) } - return executeWithRetries(request, requestOptions) + return executeWithRetries(modifiedRequest, requestOptions) } - override fun close() { - httpClient.close() - } + override fun close() = httpClient.close() - private fun isRetryable(request: HttpRequest): Boolean { + private fun isRetryable(request: HttpRequest): Boolean = // Some requests, such as when a request body is being streamed, cannot be retried because // the body data aren't available on subsequent attempts. - return request.body?.repeatable() ?: true - } + request.body?.repeatable() ?: true - private fun setRetryCountHeader(request: HttpRequest, retries: Int) { - request.headers.removeAll("x-stainless-retry-count") - request.headers.put("x-stainless-retry-count", retries.toString()) - } + private fun setRetryCountHeader(request: HttpRequest, retries: Int): HttpRequest = + request.toBuilder().replaceHeaders("X-Stainless-Retry-Count", retries.toString()).build() private fun idempotencyKey(): String = "stainless-java-retry-${UUID.randomUUID()}" - private fun maybeAddIdempotencyHeader(request: HttpRequest) { - if (idempotencyHeader != null && !request.headers.containsKey(idempotencyHeader)) { - // Set a header to uniquely identify the request when retried - request.headers.put(idempotencyHeader, idempotencyKey()) + private fun maybeAddIdempotencyHeader(request: HttpRequest): HttpRequest { + if (idempotencyHeader == null || request.headers.names().contains(idempotencyHeader)) { + return request } + + return request + .toBuilder() + // Set a header to uniquely identify the request when retried. + .putHeader(idempotencyHeader, idempotencyKey()) + .build() } private fun shouldRetry(response: HttpResponse): Boolean { // Note: this is not a standard header - val shouldRetryHeader = response.headers().get("x-should-retry").getOrNull(0) + val shouldRetryHeader = response.headers().values("X-Should-Retry").getOrNull(0) val statusCode = response.statusCode() return when { @@ -172,11 +174,10 @@ private constructor( } } - private fun shouldRetry(throwable: Throwable): Boolean { + private fun shouldRetry(throwable: Throwable): Boolean = // Only retry IOException and BraintrustIoException, other exceptions are not intended to be // retried. - return throwable is IOException || throwable is BraintrustIoException - } + throwable is IOException || throwable is BraintrustIoException private fun getRetryBackoffMillis(retries: Int, response: HttpResponse?): Duration { // About the Retry-After header: @@ -185,19 +186,19 @@ private constructor( ?.headers() ?.let { headers -> headers - .get("Retry-After-Ms") + .values("Retry-After-Ms") .getOrNull(0) ?.toFloatOrNull() ?.times(TimeUnit.MILLISECONDS.toNanos(1)) - ?: headers.get("Retry-After").getOrNull(0)?.let { retryAfter -> + ?: headers.values("Retry-After").getOrNull(0)?.let { retryAfter -> retryAfter.toFloatOrNull()?.times(TimeUnit.SECONDS.toNanos(1)) ?: try { ChronoUnit.MILLIS.between( OffsetDateTime.now(clock), OffsetDateTime.parse( retryAfter, - DateTimeFormatter.RFC_1123_DATE_TIME - ) + DateTimeFormatter.RFC_1123_DATE_TIME, + ), ) } catch (e: DateTimeParseException) { null @@ -223,27 +224,27 @@ private constructor( return Duration.ofNanos((TimeUnit.SECONDS.toNanos(1) * backoffSeconds * jitter).toLong()) } - private fun sleepAsync(millis: Long): CompletableFuture { - val future = CompletableFuture() - TIMER.schedule( - object : TimerTask() { - override fun run() { - future.complete(null) - } - }, - millis - ) - return future - } - companion object { private val TIMER = Timer("RetryingHttpClient", true) + private fun sleepAsync(millis: Long): CompletableFuture { + val future = CompletableFuture() + TIMER.schedule( + object : TimerTask() { + override fun run() { + future.complete(null) + } + }, + millis, + ) + return future + } + @JvmStatic fun builder() = Builder() } - class Builder { + class Builder internal constructor() { private var httpClient: HttpClient? = null private var clock: Clock = Clock.systemUTC() @@ -260,7 +261,7 @@ private constructor( fun build(): HttpClient = RetryingHttpClient( - checkNotNull(httpClient) { "`httpClient` is required but was not set" }, + checkRequired("httpClient", httpClient), clock, maxRetries, idempotencyHeader, diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BadRequestException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BadRequestException.kt index a373ba5e..b8c65254 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BadRequestException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BadRequestException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class BadRequestException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(400, headers, body, error) +class BadRequestException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(400, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustError.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustError.kt index e845c581..42865ed6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustError.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustError.kt @@ -2,66 +2,81 @@ package com.braintrustdata.api.errors +import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.annotation.JsonCreator import java.util.Objects -@JsonDeserialize(builder = BraintrustError.Builder::class) @NoAutoDetect class BraintrustError -constructor( - private val additionalProperties: Map, +@JsonCreator +private constructor( + @JsonAnyGetter + @ExcludeMissing + @JsonAnySetter + @get:JvmName("additionalProperties") + val additionalProperties: Map = immutableEmptyMap() ) { - @JsonAnyGetter fun additionalProperties(): Map = additionalProperties - - fun toBuilder() = Builder() - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is BraintrustError && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - return Objects.hash(additionalProperties) - } - - override fun toString() = "BraintrustError{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [BraintrustError]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [BraintrustError]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() - fun from(error: BraintrustError) = apply { - additionalProperties(error.additionalProperties) + @JvmSynthetic + internal fun from(braintrustError: BraintrustError) = apply { + additionalProperties = braintrustError.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): BraintrustError = BraintrustError(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BraintrustError]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BraintrustError = BraintrustError(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is BraintrustError && additionalProperties == other.additionalProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(additionalProperties) /* spotless:on */ + + override fun toString() = "BraintrustError{additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustServiceException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustServiceException.kt index 35d9249b..728ac6bd 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustServiceException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/BraintrustServiceException.kt @@ -1,21 +1,21 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers abstract class BraintrustServiceException @JvmOverloads constructor( private val statusCode: Int, - private val headers: ListMultimap, + private val headers: Headers, private val body: String, private val error: BraintrustError, message: String = "$statusCode: $error", - cause: Throwable? = null + cause: Throwable? = null, ) : BraintrustException(message, cause) { fun statusCode(): Int = statusCode - fun headers(): ListMultimap = headers + fun headers(): Headers = headers fun body(): String = body diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/InternalServerException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/InternalServerException.kt index e43239e8..36cc4432 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/InternalServerException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/InternalServerException.kt @@ -1,10 +1,10 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers class InternalServerException( statusCode: Int, - headers: ListMultimap, + headers: Headers, body: String, error: BraintrustError, ) : BraintrustServiceException(statusCode, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/NotFoundException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/NotFoundException.kt index 8e879cbf..ecc1a307 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/NotFoundException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/NotFoundException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class NotFoundException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(404, headers, body, error) +class NotFoundException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(404, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/PermissionDeniedException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/PermissionDeniedException.kt index 98c6f33e..27380e3e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/PermissionDeniedException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/PermissionDeniedException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class PermissionDeniedException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(403, headers, body, error) +class PermissionDeniedException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(403, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/RateLimitException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/RateLimitException.kt index d98aed03..a9352a3a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/RateLimitException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/RateLimitException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class RateLimitException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(429, headers, body, error) +class RateLimitException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(429, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnauthorizedException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnauthorizedException.kt index 72236499..57f9242f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnauthorizedException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnauthorizedException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class UnauthorizedException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(401, headers, body, error) +class UnauthorizedException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(401, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnexpectedStatusCodeException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnexpectedStatusCodeException.kt index 7482559f..7aa10d9b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnexpectedStatusCodeException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnexpectedStatusCodeException.kt @@ -1,10 +1,10 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers class UnexpectedStatusCodeException( statusCode: Int, - headers: ListMultimap, + headers: Headers, body: String, error: BraintrustError, ) : BraintrustServiceException(statusCode, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnprocessableEntityException.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnprocessableEntityException.kt index 095b1fcf..6e216b4e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnprocessableEntityException.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/errors/UnprocessableEntityException.kt @@ -1,9 +1,6 @@ package com.braintrustdata.api.errors -import com.google.common.collect.ListMultimap +import com.braintrustdata.api.core.http.Headers -class UnprocessableEntityException( - headers: ListMultimap, - body: String, - error: BraintrustError, -) : BraintrustServiceException(422, headers, body, error) +class UnprocessableEntityException(headers: Headers, body: String, error: BraintrustError) : + BraintrustServiceException(422, headers, body, error) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AISecret.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AISecret.kt new file mode 100644 index 00000000..1019fd7b --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AISecret.kt @@ -0,0 +1,486 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.time.OffsetDateTime +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +@NoAutoDetect +class AISecret +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("preview_secret") + @ExcludeMissing + private val previewSecret: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + private val updatedAt: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * Unique identifier for the AI secret + * + * @throws BraintrustInvalidDataException 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") + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") + + /** + * Date of AI secret creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun previewSecret(): Optional = + Optional.ofNullable(previewSecret.getNullable("preview_secret")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = Optional.ofNullable(type.getNullable("type")) + + /** + * Date of last AI secret update + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun updatedAt(): Optional = + Optional.ofNullable(updatedAt.getNullable("updated_at")) + + /** + * 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 [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 [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [previewSecret]. + * + * Unlike [previewSecret], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preview_secret") + @ExcludeMissing + fun _previewSecret(): JsonField = previewSecret + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): AISecret = apply { + if (validated) { + return@apply + } + + id() + name() + orgId() + created() + metadata().ifPresent { it.validate() } + previewSecret() + type() + updatedAt() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [AISecret]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AISecret]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var name: JsonField? = null + private var orgId: JsonField? = null + private var created: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var previewSecret: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var updatedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(aiSecret: AISecret) = apply { + id = aiSecret.id + name = aiSecret.name + orgId = aiSecret.orgId + created = aiSecret.created + metadata = aiSecret.metadata + previewSecret = aiSecret.previewSecret + type = aiSecret.type + updatedAt = aiSecret.updatedAt + additionalProperties = aiSecret.additionalProperties.toMutableMap() + } + + /** Unique identifier for the AI secret */ + 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 } + + /** Name of the AI secret */ + 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 } + + /** Unique identifier for the organization */ + fun orgId(orgId: String) = orgId(JsonField.of(orgId)) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgId(orgId: JsonField) = apply { this.orgId = orgId } + + /** Date of AI secret creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + fun previewSecret(previewSecret: String?) = + previewSecret(JsonField.ofNullable(previewSecret)) + + /** Alias for calling [Builder.previewSecret] with `previewSecret.orElse(null)`. */ + fun previewSecret(previewSecret: Optional) = + previewSecret(previewSecret.getOrNull()) + + /** + * Sets [Builder.previewSecret] to an arbitrary JSON value. + * + * You should usually call [Builder.previewSecret] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun previewSecret(previewSecret: JsonField) = apply { + this.previewSecret = previewSecret + } + + fun type(type: String?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + /** Date of last AI secret update */ + fun updatedAt(updatedAt: OffsetDateTime?) = updatedAt(JsonField.ofNullable(updatedAt)) + + /** Alias for calling [Builder.updatedAt] with `updatedAt.orElse(null)`. */ + fun updatedAt(updatedAt: Optional) = updatedAt(updatedAt.getOrNull()) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } + + 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 [AISecret]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AISecret = + AISecret( + checkRequired("id", id), + checkRequired("name", name), + checkRequired("orgId", orgId), + created, + metadata, + previewSecret, + type, + updatedAt, + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AISecret && id == other.id && name == other.name && orgId == other.orgId && created == other.created && metadata == other.metadata && previewSecret == other.previewSecret && type == other.type && updatedAt == other.updatedAt && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, orgId, created, metadata, previewSecret, type, updatedAt, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AISecret{id=$id, name=$name, orgId=$orgId, created=$created, metadata=$metadata, previewSecret=$previewSecret, type=$type, updatedAt=$updatedAt, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Acl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Acl.kt index 4af6e306..514087dd 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Acl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Acl.kt @@ -2,22 +2,23 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -29,654 +30,493 @@ import java.util.Optional * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. */ -@JsonDeserialize(builder = Acl.Builder::class) @NoAutoDetect class Acl +@JsonCreator private constructor( - private val id: JsonField, - private val objectType: JsonField, - private val objectId: JsonField, - private val userId: JsonField, - private val groupId: JsonField, - private val permission: JsonField, - private val restrictObjectType: JsonField, - private val roleId: JsonField, - private val _objectOrgId: JsonField, - private val created: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_object_org_id") + @ExcludeMissing + private val _objectOrgId: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonProperty("role_id") + @ExcludeMissing + private val roleId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the acl */ + /** + * Unique identifier for the acl + * + * @throws BraintrustInvalidDataException 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 object type that the ACL applies to */ - fun objectType(): ObjectType = objectType.getRequired("object_type") + /** + * The organization the ACL's referred object belongs to + * + * @throws BraintrustInvalidDataException 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 _objectOrgId(): String = _objectOrgId.getRequired("_object_org_id") - /** The id of the object the ACL applies to */ + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + fun objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Date of acl creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) /** - * Each permission permits a certain type of operation on an object in the system + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun permission(): Optional = Optional.ofNullable(permission.getNullable("permission")) - /** The object type that the ACL applies to */ - fun restrictObjectType(): Optional = + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) - /** Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided */ + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun roleId(): Optional = Optional.ofNullable(roleId.getNullable("role_id")) - /** The organization the ACL's referred object belongs to */ - fun _objectOrgId(): String = _objectOrgId.getRequired("_object_org_id") + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Date of acl creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + /** + * 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 - /** Unique identifier for the acl */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * Returns the raw JSON value of [_objectOrgId]. + * + * Unlike [_objectOrgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_object_org_id") + @ExcludeMissing + fun __objectOrgId(): JsonField = _objectOrgId - /** The object type that the ACL applies to */ - @JsonProperty("object_type") @ExcludeMissing fun _objectType() = objectType + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") @ExcludeMissing fun _objectId() = objectId + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created /** - * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("group_id") @ExcludeMissing fun _groupId() = groupId + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId /** - * Each permission permits a certain type of operation on an object in the system + * Returns the raw JSON value of [permission]. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") @ExcludeMissing fun _permission() = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an unexpected + * type. + */ @JsonProperty("restrict_object_type") @ExcludeMissing - fun _restrictObjectType() = restrictObjectType - - /** Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided */ - @JsonProperty("role_id") @ExcludeMissing fun _roleId() = roleId + fun _restrictObjectType(): JsonField = restrictObjectType - /** The organization the ACL's referred object belongs to */ - @JsonProperty("_object_org_id") @ExcludeMissing fun __objectOrgId() = _objectOrgId + /** + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role_id") @ExcludeMissing fun _roleId(): JsonField = roleId - /** Date of acl creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Acl = apply { - if (!validated) { - id() - objectType() - objectId() - userId() - groupId() - permission() - restrictObjectType() - roleId() - _objectOrgId() - created() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Acl = apply { + if (validated) { + return@apply } - return other is Acl && - this.id == other.id && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.userId == other.userId && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this._objectOrgId == other._objectOrgId && - this.created == other.created && - this.additionalProperties == other.additionalProperties + id() + _objectOrgId() + objectId() + objectType() + created() + groupId() + permission() + restrictObjectType() + roleId() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - objectType, - objectId, - userId, - groupId, - permission, - restrictObjectType, - roleId, - _objectOrgId, - created, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Acl{id=$id, objectType=$objectType, objectId=$objectId, userId=$userId, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, _objectOrgId=$_objectOrgId, created=$created, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Acl]. + * + * The following fields are required: + * ```java + * .id() + * ._objectOrgId() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Acl]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var objectType: JsonField = JsonMissing.of() - private var objectId: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var _objectOrgId: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var created: JsonField = JsonMissing.of() private var groupId: JsonField = JsonMissing.of() private var permission: JsonField = JsonMissing.of() - private var restrictObjectType: JsonField = JsonMissing.of() + private var restrictObjectType: JsonField = JsonMissing.of() private var roleId: JsonField = JsonMissing.of() - private var _objectOrgId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(acl: Acl) = apply { - this.id = acl.id - this.objectType = acl.objectType - this.objectId = acl.objectId - this.userId = acl.userId - this.groupId = acl.groupId - this.permission = acl.permission - this.restrictObjectType = acl.restrictObjectType - this.roleId = acl.roleId - this._objectOrgId = acl._objectOrgId - this.created = acl.created - additionalProperties(acl.additionalProperties) + id = acl.id + _objectOrgId = acl._objectOrgId + objectId = acl.objectId + objectType = acl.objectType + created = acl.created + groupId = acl.groupId + permission = acl.permission + restrictObjectType = acl.restrictObjectType + roleId = acl.roleId + userId = acl.userId + additionalProperties = acl.additionalProperties.toMutableMap() } /** Unique identifier for the acl */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the acl */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } - /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + /** The organization the ACL's referred object belongs to */ + fun _objectOrgId(_objectOrgId: String) = _objectOrgId(JsonField.of(_objectOrgId)) - /** The object type that the ACL applies to */ - @JsonProperty("object_type") - @ExcludeMissing - fun objectType(objectType: JsonField) = apply { this.objectType = objectType } + /** + * Sets [Builder._objectOrgId] to an arbitrary JSON value. + * + * You should usually call [Builder._objectOrgId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _objectOrgId(_objectOrgId: JsonField) = apply { + this._objectOrgId = _objectOrgId + } /** The id of the object the ACL applies to */ fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") - @ExcludeMissing + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + /** The object type that the ACL applies to */ + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun userId(userId: String) = userId(JsonField.of(userId)) + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } + + /** Date of acl creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + fun created(created: JsonField) = apply { this.created = created } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - fun groupId(groupId: String) = groupId(JsonField.of(groupId)) + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) /** - * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Sets [Builder.groupId] to an arbitrary JSON value. + * + * You should usually call [Builder.groupId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("group_id") - @ExcludeMissing fun groupId(groupId: JsonField) = apply { this.groupId = groupId } + /** Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided */ + fun permission(permission: Permission?) = permission(JsonField.ofNullable(permission)) + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) + /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.permission] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun permission(permission: Permission) = permission(JsonField.of(permission)) + fun permission(permission: JsonField) = apply { this.permission = permission } /** - * Each permission permits a certain type of operation on an object in the system - * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. */ - @JsonProperty("permission") - @ExcludeMissing - fun permission(permission: JsonField) = apply { this.permission = permission } + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) - /** The object type that the ACL applies to */ - fun restrictObjectType(restrictObjectType: RestrictObjectType) = - restrictObjectType(JsonField.of(restrictObjectType)) + /** + * Alias for calling [Builder.restrictObjectType] with `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - @ExcludeMissing - fun restrictObjectType(restrictObjectType: JsonField) = apply { + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed [AclObjectType] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } /** * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided */ - fun roleId(roleId: String) = roleId(JsonField.of(roleId)) + fun roleId(roleId: String?) = roleId(JsonField.ofNullable(roleId)) + + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("role_id") - @ExcludeMissing fun roleId(roleId: JsonField) = apply { this.roleId = roleId } - /** The organization the ACL's referred object belongs to */ - fun _objectOrgId(_objectOrgId: String) = _objectOrgId(JsonField.of(_objectOrgId)) - - /** The organization the ACL's referred object belongs to */ - @JsonProperty("_object_org_id") - @ExcludeMissing - fun _objectOrgId(_objectOrgId: JsonField) = apply { - this._objectOrgId = _objectOrgId - } + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - /** Date of acl creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - /** Date of acl creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Acl]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._objectOrgId() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Acl = Acl( - id, - objectType, - objectId, - userId, + checkRequired("id", id), + checkRequired("_objectOrgId", _objectOrgId), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + created, groupId, permission, restrictObjectType, roleId, - _objectOrgId, - created, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } - - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + return /* spotless:off */ other is Acl && id == other.id && _objectOrgId == other._objectOrgId && objectId == other.objectId && objectType == other.objectType && created == other.created && groupId == other.groupId && permission == other.permission && restrictObjectType == other.restrictObjectType && roleId == other.roleId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _objectOrgId, objectId, objectType, created, groupId, permission, restrictObjectType, roleId, userId, additionalProperties) } + /* spotless:on */ - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) + override fun hashCode(): Int = hashCode - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } - - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "Acl{id=$id, _objectOrgId=$_objectOrgId, objectId=$objectId, objectType=$objectType, created=$created, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateParams.kt index 0ce57d6e..de92b67f 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateParams.kt @@ -2,59 +2,108 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Batch update acls. This operation is idempotent, so adding acls which already exist will have no + * effect, and removing acls which do not exist will have no effect. + */ class AclBatchUpdateParams -constructor( - private val addAcls: List?, - private val removeAcls: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun addAcls(): Optional> = Optional.ofNullable(addAcls) - - fun removeAcls(): Optional> = Optional.ofNullable(removeAcls) - - @JvmSynthetic - internal fun getBody(): AclBatchUpdateBody { - return AclBatchUpdateBody( - addAcls, - removeAcls, - additionalBodyProperties, - ) - } +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * An ACL grants a certain permission or role to a certain user or group on an object. + * + * ACLs are inherited across the object hierarchy. So for example, if a user has read + * permissions on a project, they will also have read permissions on any experiment, dataset, + * etc. created within that project. + * + * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the + * ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun addAcls(): Optional> = body.addAcls() + + /** + * An ACL grants a certain permission or role to a certain user or group on an object. + * + * ACLs are inherited across the object hierarchy. So for example, if a user has read + * permissions on a project, they will also have read permissions on any experiment, dataset, + * etc. created within that project. + * + * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the + * ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun removeAcls(): Optional> = body.removeAcls() + + /** + * Returns the raw JSON value of [addAcls]. + * + * Unlike [addAcls], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _addAcls(): JsonField> = body._addAcls() + + /** + * Returns the raw JSON value of [removeAcls]. + * + * Unlike [removeAcls], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _removeAcls(): JsonField> = body._removeAcls() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + @JvmSynthetic internal fun _body(): Body = body - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = AclBatchUpdateBody.Builder::class) @NoAutoDetect - class AclBatchUpdateBody - internal constructor( - private val addAcls: List?, - private val removeAcls: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("add_acls") + @ExcludeMissing + private val addAcls: JsonField> = JsonMissing.of(), + @JsonProperty("remove_acls") + @ExcludeMissing + private val removeAcls: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * An ACL grants a certain permission or role to a certain user or group on an object. * @@ -64,8 +113,11 @@ constructor( * * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in * the ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("add_acls") fun addAcls(): List? = addAcls + fun addAcls(): Optional> = Optional.ofNullable(addAcls.getNullable("add_acls")) /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -76,57 +128,65 @@ constructor( * * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in * the ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeAcls(): Optional> = + Optional.ofNullable(removeAcls.getNullable("remove_acls")) + + /** + * Returns the raw JSON value of [addAcls]. + * + * Unlike [addAcls], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("add_acls") @ExcludeMissing fun _addAcls(): JsonField> = addAcls + + /** + * Returns the raw JSON value of [removeAcls]. + * + * Unlike [removeAcls], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("remove_acls") fun removeAcls(): List? = removeAcls + @JsonProperty("remove_acls") + @ExcludeMissing + fun _removeAcls(): JsonField> = removeAcls @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AclBatchUpdateBody && - this.addAcls == other.addAcls && - this.removeAcls == other.removeAcls && - this.additionalProperties == other.additionalProperties + addAcls().ifPresent { it.forEach { it.validate() } } + removeAcls().ifPresent { it.forEach { it.validate() } } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - addAcls, - removeAcls, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AclBatchUpdateBody{addAcls=$addAcls, removeAcls=$removeAcls, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var addAcls: List? = null - private var removeAcls: List? = null + private var addAcls: JsonField>? = null + private var removeAcls: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aclBatchUpdateBody: AclBatchUpdateBody) = apply { - this.addAcls = aclBatchUpdateBody.addAcls - this.removeAcls = aclBatchUpdateBody.removeAcls - additionalProperties(aclBatchUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + addAcls = body.addAcls.map { it.toMutableList() } + removeAcls = body.removeAcls.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** @@ -140,8 +200,33 @@ constructor( * `restrict_object_type` in the ACL, as part of a direct permission grant or as part of * a role. */ - @JsonProperty("add_acls") - fun addAcls(addAcls: List) = apply { this.addAcls = addAcls } + fun addAcls(addAcls: List?) = addAcls(JsonField.ofNullable(addAcls)) + + /** Alias for calling [Builder.addAcls] with `addAcls.orElse(null)`. */ + fun addAcls(addAcls: Optional>) = addAcls(addAcls.getOrNull()) + + /** + * Sets [Builder.addAcls] to an arbitrary JSON value. + * + * You should usually call [Builder.addAcls] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun addAcls(addAcls: JsonField>) = apply { + this.addAcls = addAcls.map { it.toMutableList() } + } + + /** + * Adds a single [AddAcl] to [addAcls]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddAcl(addAcl: AddAcl) = apply { + addAcls = + (addAcls ?: JsonField.of(mutableListOf())).also { + checkKnown("addAcls", it).add(addAcl) + } + } /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -154,87 +239,109 @@ constructor( * `restrict_object_type` in the ACL, as part of a direct permission grant or as part of * a role. */ - @JsonProperty("remove_acls") - fun removeAcls(removeAcls: List) = apply { this.removeAcls = removeAcls } + fun removeAcls(removeAcls: List?) = + removeAcls(JsonField.ofNullable(removeAcls)) + + /** Alias for calling [Builder.removeAcls] with `removeAcls.orElse(null)`. */ + fun removeAcls(removeAcls: Optional>) = + removeAcls(removeAcls.getOrNull()) + + /** + * Sets [Builder.removeAcls] to an arbitrary JSON value. + * + * You should usually call [Builder.removeAcls] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun removeAcls(removeAcls: JsonField>) = apply { + this.removeAcls = removeAcls.map { it.toMutableList() } + } + + /** + * Adds a single [RemoveAcl] to [removeAcls]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveAcl(removeAcl: RemoveAcl) = apply { + removeAcls = + (removeAcls ?: JsonField.of(mutableListOf())).also { + checkKnown("removeAcls", it).add(removeAcl) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AclBatchUpdateBody = - AclBatchUpdateBody( - addAcls?.toUnmodifiable(), - removeAcls?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body( + (addAcls ?: JsonMissing.of()).map { it.toImmutable() }, + (removeAcls ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && addAcls == other.addAcls && removeAcls == other.removeAcls && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AclBatchUpdateParams && - this.addAcls == other.addAcls && - this.removeAcls == other.removeAcls && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(addAcls, removeAcls, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - addAcls, - removeAcls, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AclBatchUpdateParams{addAcls=$addAcls, removeAcls=$removeAcls, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{addAcls=$addAcls, removeAcls=$removeAcls, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): AclBatchUpdateParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AclBatchUpdateParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclBatchUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var addAcls: MutableList = mutableListOf() - private var removeAcls: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(aclBatchUpdateParams: AclBatchUpdateParams) = apply { - this.addAcls(aclBatchUpdateParams.addAcls ?: listOf()) - this.removeAcls(aclBatchUpdateParams.removeAcls ?: listOf()) - additionalQueryParams(aclBatchUpdateParams.additionalQueryParams) - additionalHeaders(aclBatchUpdateParams.additionalHeaders) - additionalBodyProperties(aclBatchUpdateParams.additionalBodyProperties) + body = aclBatchUpdateParams.body.toBuilder() + additionalHeaders = aclBatchUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = aclBatchUpdateParams.additionalQueryParams.toBuilder() } /** @@ -247,22 +354,26 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in * the ACL, as part of a direct permission grant or as part of a role. */ - fun addAcls(addAcls: List) = apply { - this.addAcls.clear() - this.addAcls.addAll(addAcls) - } + fun addAcls(addAcls: List?) = apply { body.addAcls(addAcls) } + + /** Alias for calling [Builder.addAcls] with `addAcls.orElse(null)`. */ + fun addAcls(addAcls: Optional>) = addAcls(addAcls.getOrNull()) /** - * An ACL grants a certain permission or role to a certain user or group on an object. + * Sets [Builder.addAcls] to an arbitrary JSON value. * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, - * dataset, etc. created within that project. + * You should usually call [Builder.addAcls] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun addAcls(addAcls: JsonField>) = apply { body.addAcls(addAcls) } + + /** + * Adds a single [AddAcl] to [addAcls]. * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in - * the ACL, as part of a direct permission grant or as part of a role. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addAddAcl(addAcl: AddAcl) = apply { this.addAcls.add(addAcl) } + fun addAddAcl(addAcl: AddAcl) = apply { body.addAddAcl(addAcl) } /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -274,84 +385,156 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in * the ACL, as part of a direct permission grant or as part of a role. */ - fun removeAcls(removeAcls: List) = apply { - this.removeAcls.clear() - this.removeAcls.addAll(removeAcls) - } + fun removeAcls(removeAcls: List?) = apply { body.removeAcls(removeAcls) } + + /** Alias for calling [Builder.removeAcls] with `removeAcls.orElse(null)`. */ + fun removeAcls(removeAcls: Optional>) = removeAcls(removeAcls.getOrNull()) /** - * An ACL grants a certain permission or role to a certain user or group on an object. + * Sets [Builder.removeAcls] to an arbitrary JSON value. * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, - * dataset, etc. created within that project. + * You should usually call [Builder.removeAcls] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun removeAcls(removeAcls: JsonField>) = apply { + body.removeAcls(removeAcls) + } + + /** + * Adds a single [RemoveAcl] to [removeAcls]. * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in - * the ACL, as part of a direct permission grant or as part of a role. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addRemoveAcl(removeAcl: RemoveAcl) = apply { this.removeAcls.add(removeAcl) } + fun addRemoveAcl(removeAcl: RemoveAcl) = apply { body.addRemoveAcl(removeAcl) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [AclBatchUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): AclBatchUpdateParams = AclBatchUpdateParams( - if (addAcls.size == 0) null else addAcls.toUnmodifiable(), - if (removeAcls.size == 0) null else removeAcls.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -365,510 +548,398 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. */ - @JsonDeserialize(builder = AddAcl.Builder::class) @NoAutoDetect class AddAcl + @JsonCreator private constructor( - private val objectType: ObjectType?, - private val objectId: String?, - private val userId: String?, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonProperty("role_id") + @ExcludeMissing + private val roleId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) + + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun permission(): Optional = + Optional.ofNullable(permission.getNullable("permission")) - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun roleId(): Optional = Optional.ofNullable(roleId.getNullable("role_id")) /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("user_id") fun userId(): String? = userId + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) /** - * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("group_id") fun groupId(): String? = groupId + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId /** - * Each permission permits a certain type of operation on an object in the system + * Returns the raw JSON value of [permission]. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") fun permission(): Permission? = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role_id") @ExcludeMissing fun _roleId(): JsonField = roleId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("role_id") fun roleId(): String? = roleId + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): AddAcl = apply { + if (validated) { + return@apply } - return other is AddAcl && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.userId == other.userId && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.additionalProperties == other.additionalProperties + objectId() + objectType() + groupId() + permission() + restrictObjectType() + roleId() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - userId, - groupId, - permission, - restrictObjectType, - roleId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AddAcl{objectType=$objectType, objectId=$objectId, userId=$userId, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AddAcl]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [AddAcl]. */ + class Builder internal constructor() { - private var objectType: ObjectType? = null - private var objectId: String? = null - private var userId: String? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var groupId: JsonField = JsonMissing.of() + private var permission: JsonField = JsonMissing.of() + private var restrictObjectType: JsonField = JsonMissing.of() + private var roleId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(addAcl: AddAcl) = apply { - this.objectType = addAcl.objectType - this.objectId = addAcl.objectId - this.userId = addAcl.userId - this.groupId = addAcl.groupId - this.permission = addAcl.permission - this.restrictObjectType = addAcl.restrictObjectType - this.roleId = addAcl.roleId - additionalProperties(addAcl.additionalProperties) + objectId = addAcl.objectId + objectType = addAcl.objectType + groupId = addAcl.groupId + permission = addAcl.permission + restrictObjectType = addAcl.restrictObjectType + roleId = addAcl.roleId + userId = addAcl.userId + additionalProperties = addAcl.additionalProperties.toMutableMap() } - /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } - /** - * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided - */ - @JsonProperty("group_id") - fun groupId(groupId: String) = apply { this.groupId = groupId } + /** The object type that the ACL applies to */ + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.objectType] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into - * roles + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } - - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { - this.restrictObjectType = restrictObjectType - } + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be + * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("role_id") fun roleId(roleId: String) = apply { this.roleId = roleId } + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): AddAcl = - AddAcl( - checkNotNull(objectType) { "`objectType` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - userId, - groupId, - permission, - restrictObjectType, - roleId, - additionalProperties.toUnmodifiable(), - ) - } + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** + * Sets [Builder.groupId] to an arbitrary JSON value. + * + * You should usually call [Builder.groupId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupId(groupId: JsonField) = apply { this.groupId = groupId } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun permission(permission: Permission?) = permission(JsonField.ofNullable(permission)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) - return other is ObjectType && this.value == other.value + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + /** + * When setting a permission directly, optionally restricts the permission grant to just + * the specified object type. Cannot be set alongside a `role_id`. + */ + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { + this.restrictObjectType = restrictObjectType } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be + * provided + */ + fun roleId(roleId: String?) = roleId(JsonField.ofNullable(roleId)) - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun roleId(roleId: JsonField) = apply { this.roleId = roleId } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } - return other is Permission && this.value == other.value + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) } - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) } - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + /** + * Returns an immutable instance of [AddAcl]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AddAcl = + AddAcl( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + groupId, + permission, + restrictObjectType, + roleId, + userId, + additionalProperties.toImmutable(), + ) } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } + return /* spotless:off */ other is AddAcl && objectId == other.objectId && objectType == other.objectType && groupId == other.groupId && permission == other.permission && restrictObjectType == other.restrictObjectType && roleId == other.roleId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, groupId, permission, restrictObjectType, roleId, userId, additionalProperties) } + /* spotless:on */ - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun hashCode(): Int = hashCode - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "AddAcl{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" } /** @@ -881,159 +952,298 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. */ - @JsonDeserialize(builder = RemoveAcl.Builder::class) @NoAutoDetect class RemoveAcl + @JsonCreator private constructor( - private val objectType: ObjectType?, - private val objectId: String?, - private val userId: String?, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonProperty("role_id") + @ExcludeMissing + private val roleId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) + + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun permission(): Optional = + Optional.ofNullable(permission.getNullable("permission")) + + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) + + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun roleId(): Optional = Optional.ofNullable(roleId.getNullable("role_id")) /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("user_id") fun userId(): String? = userId + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) /** - * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("group_id") fun groupId(): String? = groupId + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType /** - * Each permission permits a certain type of operation on an object in the system + * Returns the raw JSON value of [groupId]. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") fun permission(): Permission? = permission + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role_id") @ExcludeMissing fun _roleId(): JsonField = roleId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("role_id") fun roleId(): String? = roleId + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RemoveAcl = apply { + if (validated) { + return@apply } - return other is RemoveAcl && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.userId == other.userId && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - userId, - groupId, - permission, - restrictObjectType, - roleId, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + groupId() + permission() + restrictObjectType() + roleId() + userId() + validated = true } - override fun toString() = - "RemoveAcl{objectType=$objectType, objectId=$objectId, userId=$userId, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RemoveAcl]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RemoveAcl]. */ + class Builder internal constructor() { - private var objectType: ObjectType? = null - private var objectId: String? = null - private var userId: String? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var groupId: JsonField = JsonMissing.of() + private var permission: JsonField = JsonMissing.of() + private var restrictObjectType: JsonField = JsonMissing.of() + private var roleId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(removeAcl: RemoveAcl) = apply { - this.objectType = removeAcl.objectType - this.objectId = removeAcl.objectId - this.userId = removeAcl.userId - this.groupId = removeAcl.groupId - this.permission = removeAcl.permission - this.restrictObjectType = removeAcl.restrictObjectType - this.roleId = removeAcl.roleId - additionalProperties(removeAcl.additionalProperties) + objectId = removeAcl.objectId + objectType = removeAcl.objectType + groupId = removeAcl.groupId + permission = removeAcl.permission + restrictObjectType = removeAcl.restrictObjectType + roleId = removeAcl.roleId + userId = removeAcl.userId + additionalProperties = removeAcl.additionalProperties.toMutableMap() } - /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + + /** The object type that the ACL applies to */ + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("group_id") - fun groupId(groupId: String) = apply { this.groupId = groupId } + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.groupId] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into - * roles + * You should usually call [Builder.groupId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun groupId(groupId: JsonField) = apply { this.groupId = groupId } - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun permission(permission: Permission?) = permission(JsonField.ofNullable(permission)) + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } + + /** + * When setting a permission directly, optionally restricts the permission grant to just + * the specified object type. Cannot be set alongside a `role_id`. + */ + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } @@ -1041,349 +1251,111 @@ constructor( * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be * provided */ - @JsonProperty("role_id") fun roleId(roleId: String) = apply { this.roleId = roleId } + fun roleId(roleId: String?) = roleId(JsonField.ofNullable(roleId)) + + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) + + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun roleId(roleId: JsonField) = apply { this.roleId = roleId } + + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RemoveAcl]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RemoveAcl = RemoveAcl( - checkNotNull(objectType) { "`objectType` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - userId, + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), groupId, permission, restrictObjectType, roleId, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } - - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() + return /* spotless:off */ other is RemoveAcl && objectId == other.objectId && objectType == other.objectType && groupId == other.groupId && permission == other.permission && restrictObjectType == other.restrictObjectType && roleId == other.roleId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, groupId, permission, restrictObjectType, roleId, userId, additionalProperties) } + /* spotless:on */ - @JvmField val DELETE = Permission(JsonField.of("delete")) + override fun hashCode(): Int = hashCode - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, - } + override fun toString() = + "RemoveAcl{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" + } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + return /* spotless:off */ other is AclBatchUpdateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "AclBatchUpdateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponse.kt index 4d9d89b7..ee549d63 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponse.kt @@ -7,26 +7,30 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects -@JsonDeserialize(builder = AclBatchUpdateResponse.Builder::class) @NoAutoDetect class AclBatchUpdateResponse +@JsonCreator private constructor( - private val addedAcls: JsonField>, - private val removedAcls: JsonField>, - private val additionalProperties: Map, + @JsonProperty("added_acls") + @ExcludeMissing + private val addedAcls: JsonField> = JsonMissing.of(), + @JsonProperty("removed_acls") + @ExcludeMissing + private val removedAcls: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * An ACL grants a certain permission or role to a certain user or group on an object. * @@ -36,6 +40,9 @@ private constructor( * * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException 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 addedAcls(): List = addedAcls.getRequired("added_acls") @@ -48,89 +55,72 @@ private constructor( * * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. + * + * @throws BraintrustInvalidDataException 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 removedAcls(): List = removedAcls.getRequired("removed_acls") /** - * An ACL grants a certain permission or role to a certain user or group on an object. - * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, dataset, - * etc. created within that project. + * Returns the raw JSON value of [addedAcls]. * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the - * ACL, as part of a direct permission grant or as part of a role. + * Unlike [addedAcls], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("added_acls") @ExcludeMissing fun _addedAcls() = addedAcls + @JsonProperty("added_acls") @ExcludeMissing fun _addedAcls(): JsonField> = addedAcls /** - * An ACL grants a certain permission or role to a certain user or group on an object. + * Returns the raw JSON value of [removedAcls]. * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, dataset, - * etc. created within that project. - * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the - * ACL, as part of a direct permission grant or as part of a role. + * Unlike [removedAcls], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("removed_acls") @ExcludeMissing fun _removedAcls() = removedAcls + @JsonProperty("removed_acls") + @ExcludeMissing + fun _removedAcls(): JsonField> = removedAcls @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): AclBatchUpdateResponse = apply { - if (!validated) { - addedAcls().forEach { it.validate() } - removedAcls().forEach { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): AclBatchUpdateResponse = apply { + if (validated) { + return@apply } - return other is AclBatchUpdateResponse && - this.addedAcls == other.addedAcls && - this.removedAcls == other.removedAcls && - this.additionalProperties == other.additionalProperties + addedAcls().forEach { it.validate() } + removedAcls().forEach { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - addedAcls, - removedAcls, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AclBatchUpdateResponse{addedAcls=$addedAcls, removedAcls=$removedAcls, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclBatchUpdateResponse]. + * + * The following fields are required: + * ```java + * .addedAcls() + * .removedAcls() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [AclBatchUpdateResponse]. */ + class Builder internal constructor() { - private var addedAcls: JsonField> = JsonMissing.of() - private var removedAcls: JsonField> = JsonMissing.of() + private var addedAcls: JsonField>? = null + private var removedAcls: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(aclBatchUpdateResponse: AclBatchUpdateResponse) = apply { - this.addedAcls = aclBatchUpdateResponse.addedAcls - this.removedAcls = aclBatchUpdateResponse.removedAcls - additionalProperties(aclBatchUpdateResponse.additionalProperties) + addedAcls = aclBatchUpdateResponse.addedAcls.map { it.toMutableList() } + removedAcls = aclBatchUpdateResponse.removedAcls.map { it.toMutableList() } + additionalProperties = aclBatchUpdateResponse.additionalProperties.toMutableMap() } /** @@ -146,18 +136,27 @@ private constructor( fun addedAcls(addedAcls: List) = addedAcls(JsonField.of(addedAcls)) /** - * An ACL grants a certain permission or role to a certain user or group on an object. + * Sets [Builder.addedAcls] to an arbitrary JSON value. * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, - * dataset, etc. created within that project. + * You should usually call [Builder.addedAcls] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun addedAcls(addedAcls: JsonField>) = apply { + this.addedAcls = addedAcls.map { it.toMutableList() } + } + + /** + * Adds a single [Acl] to [addedAcls]. * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in - * the ACL, as part of a direct permission grant or as part of a role. + * @throws IllegalStateException if the field was previously set to a non-list. */ - @JsonProperty("added_acls") - @ExcludeMissing - fun addedAcls(addedAcls: JsonField>) = apply { this.addedAcls = addedAcls } + fun addAddedAcl(addedAcl: Acl) = apply { + addedAcls = + (addedAcls ?: JsonField.of(mutableListOf())).also { + checkKnown("addedAcls", it).add(addedAcl) + } + } /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -172,40 +171,82 @@ private constructor( fun removedAcls(removedAcls: List) = removedAcls(JsonField.of(removedAcls)) /** - * An ACL grants a certain permission or role to a certain user or group on an object. + * Sets [Builder.removedAcls] to an arbitrary JSON value. * - * ACLs are inherited across the object hierarchy. So for example, if a user has read - * permissions on a project, they will also have read permissions on any experiment, - * dataset, etc. created within that project. - * - * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in - * the ACL, as part of a direct permission grant or as part of a role. + * You should usually call [Builder.removedAcls] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("removed_acls") - @ExcludeMissing fun removedAcls(removedAcls: JsonField>) = apply { - this.removedAcls = removedAcls + this.removedAcls = removedAcls.map { it.toMutableList() } + } + + /** + * Adds a single [Acl] to [removedAcls]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemovedAcl(removedAcl: Acl) = apply { + removedAcls = + (removedAcls ?: JsonField.of(mutableListOf())).also { + checkKnown("removedAcls", it).add(removedAcl) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [AclBatchUpdateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .addedAcls() + * .removedAcls() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AclBatchUpdateResponse = AclBatchUpdateResponse( - addedAcls.map { it.toUnmodifiable() }, - removedAcls.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + checkRequired("addedAcls", addedAcls).map { it.toImmutable() }, + checkRequired("removedAcls", removedAcls).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AclBatchUpdateResponse && addedAcls == other.addedAcls && removedAcls == other.removedAcls && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(addedAcls, removedAcls, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AclBatchUpdateResponse{addedAcls=$addedAcls, removedAcls=$removedAcls, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclCreateParams.kt index df9d7d5e..27d4477a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclCreateParams.kt @@ -2,67 +2,155 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new acl. If there is an existing acl with the same contents as the one specified in the + * request, will return the existing acl unmodified + */ class AclCreateParams -constructor( - private val objectId: String, - private val objectType: ObjectType, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val userId: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun groupId(): Optional = Optional.ofNullable(groupId) - - fun permission(): Optional = Optional.ofNullable(permission) - - fun restrictObjectType(): Optional = Optional.ofNullable(restrictObjectType) - - fun roleId(): Optional = Optional.ofNullable(roleId) - - fun userId(): Optional = Optional.ofNullable(userId) - - @JvmSynthetic - internal fun getBody(): AclCreateBody { - return AclCreateBody( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalBodyProperties, - ) - } +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() + + /** + * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun groupId(): Optional = body.groupId() + + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun permission(): Optional = body.permission() + + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = body.restrictObjectType() + + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun roleId(): Optional = body.roleId() + + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _groupId(): JsonField = body._groupId() + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _permission(): JsonField = body._permission() + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _restrictObjectType(): JsonField = body._restrictObjectType() + + /** + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _roleId(): JsonField = body._roleId() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -74,153 +162,298 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. */ - @JsonDeserialize(builder = AclCreateBody.Builder::class) @NoAutoDetect - class AclCreateBody - internal constructor( - private val objectId: String?, - private val objectType: ObjectType?, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val userId: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonProperty("role_id") + @ExcludeMissing + private val roleId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("group_id") fun groupId(): String? = groupId + fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) /** - * Each permission permits a certain type of operation on an object in the system + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("permission") fun permission(): Permission? = permission + fun permission(): Optional = + Optional.ofNullable(permission.getNullable("permission")) - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) /** * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("role_id") fun roleId(): String? = roleId + fun roleId(): Optional = Optional.ofNullable(roleId.getNullable("role_id")) /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("restrict_object_type") + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType + + /** + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role_id") @ExcludeMissing fun _roleId(): JsonField = roleId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("user_id") fun userId(): String? = userId + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AclCreateBody && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.userId == other.userId && - this.additionalProperties == other.additionalProperties + objectId() + objectType() + groupId() + permission() + restrictObjectType() + roleId() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AclCreateBody{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var objectId: String? = null - private var objectType: ObjectType? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null - private var userId: String? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var groupId: JsonField = JsonMissing.of() + private var permission: JsonField = JsonMissing.of() + private var restrictObjectType: JsonField = JsonMissing.of() + private var roleId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aclCreateBody: AclCreateBody) = apply { - this.objectId = aclCreateBody.objectId - this.objectType = aclCreateBody.objectType - this.groupId = aclCreateBody.groupId - this.permission = aclCreateBody.permission - this.restrictObjectType = aclCreateBody.restrictObjectType - this.roleId = aclCreateBody.roleId - this.userId = aclCreateBody.userId - additionalProperties(aclCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + objectId = body.objectId + objectType = body.objectType + groupId = body.groupId + permission = body.permission + restrictObjectType = body.restrictObjectType + roleId = body.roleId + userId = body.userId + additionalProperties = body.additionalProperties.toMutableMap() } /** The id of the object the ACL applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("group_id") - fun groupId(groupId: String) = apply { this.groupId = groupId } + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) + + /** + * Sets [Builder.groupId] to an arbitrary JSON value. + * + * You should usually call [Builder.groupId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupId(groupId: JsonField) = apply { this.groupId = groupId } /** - * Each permission permits a certain type of operation on an object in the system + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun permission(permission: Permission?) = permission(JsonField.ofNullable(permission)) + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into - * roles + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun permission(permission: JsonField) = apply { + this.permission = permission + } - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + /** + * When setting a permission directly, optionally restricts the permission grant to just + * the specified object type. Cannot be set alongside a `role_id`. + */ + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } @@ -228,535 +461,389 @@ constructor( * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be * provided */ - @JsonProperty("role_id") fun roleId(roleId: String) = apply { this.roleId = roleId } + fun roleId(roleId: String?) = roleId(JsonField.ofNullable(roleId)) + + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) + + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun roleId(roleId: JsonField) = apply { this.roleId = roleId } /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AclCreateBody = - AclCreateBody( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, + 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 + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), groupId, permission, restrictObjectType, roleId, userId, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && objectId == other.objectId && objectType == other.objectType && groupId == other.groupId && permission == other.permission && restrictObjectType == other.restrictObjectType && roleId == other.roleId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AclCreateParams && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.userId == other.userId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, groupId, permission, restrictObjectType, roleId, userId, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AclCreateParams{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclCreateParams]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclCreateParams]. */ @NoAutoDetect - class Builder { - - private var objectId: String? = null - private var objectType: ObjectType? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null - private var userId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(aclCreateParams: AclCreateParams) = apply { - this.objectId = aclCreateParams.objectId - this.objectType = aclCreateParams.objectType - this.groupId = aclCreateParams.groupId - this.permission = aclCreateParams.permission - this.restrictObjectType = aclCreateParams.restrictObjectType - this.roleId = aclCreateParams.roleId - this.userId = aclCreateParams.userId - additionalQueryParams(aclCreateParams.additionalQueryParams) - additionalHeaders(aclCreateParams.additionalHeaders) - additionalBodyProperties(aclCreateParams.additionalBodyProperties) + body = aclCreateParams.body.toBuilder() + additionalHeaders = aclCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = aclCreateParams.additionalQueryParams.toBuilder() } /** The id of the object the ACL applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - fun groupId(groupId: String) = apply { this.groupId = groupId } + fun groupId(groupId: String?) = apply { body.groupId(groupId) } + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.groupId] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * You should usually call [Builder.groupId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun permission(permission: Permission) = apply { this.permission = permission } + fun groupId(groupId: JsonField) = apply { body.groupId(groupId) } - /** The object type that the ACL applies to */ - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { - this.restrictObjectType = restrictObjectType - } + /** Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided */ + fun permission(permission: Permission?) = apply { body.permission(permission) } + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun roleId(roleId: String) = apply { this.roleId = roleId } + fun permission(permission: JsonField) = apply { body.permission(permission) } /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. */ - fun userId(userId: String) = apply { this.userId = userId } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun restrictObjectType(restrictObjectType: AclObjectType?) = apply { + body.restrictObjectType(restrictObjectType) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Alias for calling [Builder.restrictObjectType] with `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed [AclObjectType] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { + body.restrictObjectType(restrictObjectType) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun roleId(roleId: String?) = apply { body.roleId(roleId) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun roleId(roleId: JsonField) = apply { body.roleId(roleId) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + */ + fun userId(userId: String?) = apply { body.userId(userId) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.additionalProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + body.putAdditionalProperty(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.putAllAdditionalProperties(additionalBodyProperties) } - fun build(): AclCreateParams = - AclCreateParams( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - @JvmField val UPDATE = Permission(JsonField.of("update")) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - @JvmField val DELETE = Permission(JsonField.of("delete")) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - return other is RestrictObjectType && this.value == other.value + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + /** + * Returns an immutable instance of [AclCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AclCreateParams = + AclCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is AclCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "AclCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclDeleteParams.kt index 6ffaefdf..1aaf3f66 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an acl object by its id */ class AclDeleteParams -constructor( +private constructor( private val aclId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Acl id */ fun aclId(): String = aclId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AclDeleteParams && - this.aclId == other.aclId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - aclId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "AclDeleteParams{aclId=$aclId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclDeleteParams]. + * + * The following fields are required: + * ```java + * .aclId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aclId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(aclDeleteParams: AclDeleteParams) = apply { - this.aclId = aclDeleteParams.aclId - additionalQueryParams(aclDeleteParams.additionalQueryParams) - additionalHeaders(aclDeleteParams.additionalHeaders) - additionalBodyProperties(aclDeleteParams.additionalBodyProperties) + aclId = aclDeleteParams.aclId + additionalHeaders = aclDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = aclDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = aclDeleteParams.additionalBodyProperties.toMutableMap() } /** Acl id */ fun aclId(aclId: String) = apply { this.aclId = aclId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [AclDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .aclId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AclDeleteParams = AclDeleteParams( - checkNotNull(aclId) { "`aclId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("aclId", aclId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AclDeleteParams && aclId == other.aclId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aclId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "AclDeleteParams{aclId=$aclId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParams.kt index c9af483d..5f778de3 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParams.kt @@ -2,67 +2,152 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Delete a single acl */ class AclFindAndDeleteParams -constructor( - private val objectId: String, - private val objectType: ObjectType, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val userId: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun groupId(): Optional = Optional.ofNullable(groupId) - - fun permission(): Optional = Optional.ofNullable(permission) - - fun restrictObjectType(): Optional = Optional.ofNullable(restrictObjectType) - - fun roleId(): Optional = Optional.ofNullable(roleId) - - fun userId(): Optional = Optional.ofNullable(userId) - - @JvmSynthetic - internal fun getBody(): AclFindAndDeleteBody { - return AclFindAndDeleteBody( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalBodyProperties, - ) - } +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() + + /** + * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun groupId(): Optional = body.groupId() + + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun permission(): Optional = body.permission() + + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = body.restrictObjectType() + + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun roleId(): Optional = body.roleId() + + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _groupId(): JsonField = body._groupId() + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _permission(): JsonField = body._permission() + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _restrictObjectType(): JsonField = body._restrictObjectType() + + /** + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _roleId(): JsonField = body._roleId() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams /** * An ACL grants a certain permission or role to a certain user or group on an object. @@ -74,153 +159,298 @@ constructor( * To restrict a grant to a particular sub-object, you may specify `restrict_object_type` in the * ACL, as part of a direct permission grant or as part of a role. */ - @JsonDeserialize(builder = AclFindAndDeleteBody.Builder::class) @NoAutoDetect - class AclFindAndDeleteBody - internal constructor( - private val objectId: String?, - private val objectType: ObjectType?, - private val groupId: String?, - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val roleId: String?, - private val userId: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonProperty("role_id") + @ExcludeMissing + private val roleId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The id of the object the ACL applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * The id of the object the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("group_id") fun groupId(): String? = groupId + fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) /** - * Each permission permits a certain type of operation on an object in the system + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("permission") fun permission(): Permission? = permission + fun permission(): Optional = + Optional.ofNullable(permission.getNullable("permission")) - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + /** + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) /** * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("role_id") fun roleId(): String? = roleId + fun roleId(): Optional = Optional.ofNullable(roleId.getNullable("role_id")) /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("user_id") fun userId(): String? = userId + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("restrict_object_type") + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType + + /** + * Returns the raw JSON value of [roleId]. + * + * Unlike [roleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role_id") @ExcludeMissing fun _roleId(): JsonField = roleId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AclFindAndDeleteBody && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.userId == other.userId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + groupId() + permission() + restrictObjectType() + roleId() + userId() + validated = true } - override fun toString() = - "AclFindAndDeleteBody{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var objectId: String? = null - private var objectType: ObjectType? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null - private var userId: String? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var groupId: JsonField = JsonMissing.of() + private var permission: JsonField = JsonMissing.of() + private var restrictObjectType: JsonField = JsonMissing.of() + private var roleId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aclFindAndDeleteBody: AclFindAndDeleteBody) = apply { - this.objectId = aclFindAndDeleteBody.objectId - this.objectType = aclFindAndDeleteBody.objectType - this.groupId = aclFindAndDeleteBody.groupId - this.permission = aclFindAndDeleteBody.permission - this.restrictObjectType = aclFindAndDeleteBody.restrictObjectType - this.roleId = aclFindAndDeleteBody.roleId - this.userId = aclFindAndDeleteBody.userId - additionalProperties(aclFindAndDeleteBody.additionalProperties) + internal fun from(body: Body) = apply { + objectId = body.objectId + objectType = body.objectType + groupId = body.groupId + permission = body.permission + restrictObjectType = body.restrictObjectType + roleId = body.roleId + userId = body.userId + additionalProperties = body.additionalProperties.toMutableMap() } /** The id of the object the ACL applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("group_id") - fun groupId(groupId: String) = apply { this.groupId = groupId } + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.groupId] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into - * roles + * You should usually call [Builder.groupId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun groupId(groupId: JsonField) = apply { this.groupId = groupId } - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + /** + * Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun permission(permission: Permission?) = permission(JsonField.ofNullable(permission)) + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } + + /** + * When setting a permission directly, optionally restricts the permission grant to just + * the specified object type. Cannot be set alongside a `role_id`. + */ + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } @@ -228,535 +458,393 @@ constructor( * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be * provided */ - @JsonProperty("role_id") fun roleId(roleId: String) = apply { this.roleId = roleId } + fun roleId(roleId: String?) = roleId(JsonField.ofNullable(roleId)) + + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) + + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun roleId(roleId: JsonField) = apply { this.roleId = roleId } /** * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AclFindAndDeleteBody = - AclFindAndDeleteBody( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, + 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 + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), groupId, permission, restrictObjectType, roleId, userId, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && objectId == other.objectId && objectType == other.objectType && groupId == other.groupId && permission == other.permission && restrictObjectType == other.restrictObjectType && roleId == other.roleId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AclFindAndDeleteParams && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.groupId == other.groupId && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.roleId == other.roleId && - this.userId == other.userId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, groupId, permission, restrictObjectType, roleId, userId, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - objectId, - objectType, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AclFindAndDeleteParams{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{objectId=$objectId, objectType=$objectType, groupId=$groupId, permission=$permission, restrictObjectType=$restrictObjectType, roleId=$roleId, userId=$userId, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclFindAndDeleteParams]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclFindAndDeleteParams]. */ @NoAutoDetect - class Builder { - - private var objectId: String? = null - private var objectType: ObjectType? = null - private var groupId: String? = null - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null - private var roleId: String? = null - private var userId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(aclFindAndDeleteParams: AclFindAndDeleteParams) = apply { - this.objectId = aclFindAndDeleteParams.objectId - this.objectType = aclFindAndDeleteParams.objectType - this.groupId = aclFindAndDeleteParams.groupId - this.permission = aclFindAndDeleteParams.permission - this.restrictObjectType = aclFindAndDeleteParams.restrictObjectType - this.roleId = aclFindAndDeleteParams.roleId - this.userId = aclFindAndDeleteParams.userId - additionalQueryParams(aclFindAndDeleteParams.additionalQueryParams) - additionalHeaders(aclFindAndDeleteParams.additionalHeaders) - additionalBodyProperties(aclFindAndDeleteParams.additionalBodyProperties) + body = aclFindAndDeleteParams.body.toBuilder() + additionalHeaders = aclFindAndDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = aclFindAndDeleteParams.additionalQueryParams.toBuilder() } /** The id of the object the ACL applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** * Id of the group the ACL applies to. Exactly one of `user_id` and `group_id` will be * provided */ - fun groupId(groupId: String) = apply { this.groupId = groupId } + fun groupId(groupId: String?) = apply { body.groupId(groupId) } + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.groupId] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * You should usually call [Builder.groupId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun permission(permission: Permission) = apply { this.permission = permission } + fun groupId(groupId: JsonField) = apply { body.groupId(groupId) } - /** The object type that the ACL applies to */ - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { - this.restrictObjectType = restrictObjectType - } + /** Permission the ACL grants. Exactly one of `permission` and `role_id` will be provided */ + fun permission(permission: Permission?) = apply { body.permission(permission) } + + /** Alias for calling [Builder.permission] with `permission.orElse(null)`. */ + fun permission(permission: Optional) = permission(permission.getOrNull()) /** - * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun roleId(roleId: String) = apply { this.roleId = roleId } + fun permission(permission: JsonField) = apply { body.permission(permission) } /** - * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be - * provided + * When setting a permission directly, optionally restricts the permission grant to just the + * specified object type. Cannot be set alongside a `role_id`. */ - fun userId(userId: String) = apply { this.userId = userId } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun restrictObjectType(restrictObjectType: AclObjectType?) = apply { + body.restrictObjectType(restrictObjectType) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } - - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Alias for calling [Builder.restrictObjectType] with `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed [AclObjectType] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { + body.restrictObjectType(restrictObjectType) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** + * Id of the role the ACL grants. Exactly one of `permission` and `role_id` will be provided + */ + fun roleId(roleId: String?) = apply { body.roleId(roleId) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** Alias for calling [Builder.roleId] with `roleId.orElse(null)`. */ + fun roleId(roleId: Optional) = roleId(roleId.getOrNull()) - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Sets [Builder.roleId] to an arbitrary JSON value. + * + * You should usually call [Builder.roleId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun roleId(roleId: JsonField) = apply { body.roleId(roleId) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Id of the user the ACL applies to. Exactly one of `user_id` and `group_id` will be + * provided + */ + fun userId(userId: String?) = apply { body.userId(userId) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.additionalProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + body.putAdditionalProperty(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.putAllAdditionalProperties(additionalBodyProperties) } - fun build(): AclFindAndDeleteParams = - AclFindAndDeleteParams( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - groupId, - permission, - restrictObjectType, - roleId, - userId, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - @JvmField val UPDATE = Permission(JsonField.of("update")) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - @JvmField val DELETE = Permission(JsonField.of("delete")) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - return other is RestrictObjectType && this.value == other.value + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + /** + * Returns an immutable instance of [AclFindAndDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AclFindAndDeleteParams = + AclFindAndDeleteParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is AclFindAndDeleteParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "AclFindAndDeleteParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPage.kt index b3c80969..5804bf46 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.AclService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all acls. The acls are sorted by creation date, with the most recently-created acls + * coming first + */ class AclListPage private constructor( private val aclsService: AclService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is AclListPage && - this.aclsService == other.aclsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is AclListPage && aclsService == other.aclsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - aclsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aclsService, params, response) /* spotless:on */ override fun toString() = "AclListPage{aclsService=$aclsService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(aclsService: AclService, params: AclListParams, response: Response) = - AclListPage( - aclsService, - params, - response, - ) + AclListPage(aclsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "AclListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [AclListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: AclListPage, - ) : Iterable { + class AutoPager(private val firstPage: AclListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPageAsync.kt index ec02e5b8..acd71877 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.AclServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all acls. The acls are sorted by creation date, with the most recently-created acls + * coming first + */ class AclListPageAsync private constructor( private val aclsService: AclServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is AclListPageAsync && - this.aclsService == other.aclsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is AclListPageAsync && aclsService == other.aclsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - aclsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aclsService, params, response) /* spotless:on */ override fun toString() = "AclListPageAsync{aclsService=$aclsService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(aclsService: AclServiceAsync, params: AclListParams, response: Response) = - AclListPageAsync( - aclsService, - params, - response, - ) + AclListPageAsync(aclsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "AclListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [AclListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: AclListPageAsync, - ) { + class AutoPager(private val firstPage: AclListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Acl) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListParams.kt index 20be8167..a49c07f5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclListParams.kt @@ -4,15 +4,14 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -22,118 +21,132 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all acls. The acls are sorted by creation date, with the most recently-created acls + * coming first + */ class AclListParams -constructor( +private constructor( private val objectId: String, - private val objectType: ObjectType, + private val objectType: AclObjectType, private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** The id of the object the ACL applies to */ fun objectId(): String = objectId - fun objectType(): ObjectType = objectType + /** The object type that the ACL applies to */ + fun objectType(): AclObjectType = objectType + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.objectId.let { params.put("object_id", listOf(it.toString())) } - this.objectType.let { params.put("object_type", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AclListParams && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - objectId, - objectType, - endingBefore, - ids, - limit, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "AclListParams{objectId=$objectId, objectType=$objectType, endingBefore=$endingBefore, ids=$ids, limit=$limit, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + put("object_id", objectId) + put("object_type", objectType.asString()) + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclListParams]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var objectId: String? = null - private var objectType: ObjectType? = null + private var objectType: AclObjectType? = null private var endingBefore: String? = null private var ids: Ids? = null private var limit: Long? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(aclListParams: AclListParams) = apply { - this.objectId = aclListParams.objectId - this.objectType = aclListParams.objectType - this.endingBefore = aclListParams.endingBefore - this.ids = aclListParams.ids - this.limit = aclListParams.limit - this.startingAfter = aclListParams.startingAfter - additionalQueryParams(aclListParams.additionalQueryParams) - additionalHeaders(aclListParams.additionalHeaders) + objectId = aclListParams.objectId + objectType = aclListParams.objectType + endingBefore = aclListParams.endingBefore + ids = aclListParams.ids + limit = aclListParams.limit + startingAfter = aclListParams.startingAfter + additionalHeaders = aclListParams.additionalHeaders.toBuilder() + additionalQueryParams = aclListParams.additionalQueryParams.toBuilder() } /** The id of the object the ACL applies to */ fun objectId(objectId: String) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { this.objectType = objectType } /** * Pagination cursor id. @@ -142,28 +155,38 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** * Pagination cursor id. @@ -172,172 +195,140 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun build(): AclListParams = - AclListParams( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - endingBefore, - ids, - limit, - startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - fun asString(): String = _value().asStringOrThrow() + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [AclListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AclListParams = + AclListParams( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + endingBefore, + ids, + limit, + startingAfter, + additionalHeaders.build(), + additionalQueryParams.build(), + ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -347,8 +338,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -371,35 +360,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -408,21 +385,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -434,12 +422,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -450,4 +438,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AclListParams && objectId == other.objectId && objectType == other.objectType && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objectId, objectType, endingBefore, ids, limit, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AclListParams{objectId=$objectId, objectType=$objectType, endingBefore=$endingBefore, ids=$ids, limit=$limit, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclObjectType.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclObjectType.kt new file mode 100644 index 00000000..90f9091e --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclObjectType.kt @@ -0,0 +1,162 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +/** The object type that the ACL applies to */ +class AclObjectType @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 ORGANIZATION = of("organization") + + @JvmField val PROJECT = of("project") + + @JvmField val EXPERIMENT = of("experiment") + + @JvmField val DATASET = of("dataset") + + @JvmField val PROMPT = of("prompt") + + @JvmField val PROMPT_SESSION = of("prompt_session") + + @JvmField val GROUP = of("group") + + @JvmField val ROLE = of("role") + + @JvmField val ORG_MEMBER = of("org_member") + + @JvmField val PROJECT_LOG = of("project_log") + + @JvmField val ORG_PROJECT = of("org_project") + + @JvmStatic fun of(value: String) = AclObjectType(JsonField.of(value)) + } + + /** An enum containing [AclObjectType]'s known values. */ + enum class Known { + ORGANIZATION, + PROJECT, + EXPERIMENT, + DATASET, + PROMPT, + PROMPT_SESSION, + GROUP, + ROLE, + ORG_MEMBER, + PROJECT_LOG, + ORG_PROJECT, + } + + /** + * An enum containing [AclObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AclObjectType] 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 { + ORGANIZATION, + PROJECT, + EXPERIMENT, + DATASET, + PROMPT, + PROMPT_SESSION, + GROUP, + ROLE, + ORG_MEMBER, + PROJECT_LOG, + ORG_PROJECT, + /** + * An enum member indicating that [AclObjectType] 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) { + ORGANIZATION -> Value.ORGANIZATION + PROJECT -> Value.PROJECT + EXPERIMENT -> Value.EXPERIMENT + DATASET -> Value.DATASET + PROMPT -> Value.PROMPT + PROMPT_SESSION -> Value.PROMPT_SESSION + GROUP -> Value.GROUP + ROLE -> Value.ROLE + ORG_MEMBER -> Value.ORG_MEMBER + PROJECT_LOG -> Value.PROJECT_LOG + ORG_PROJECT -> Value.ORG_PROJECT + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ORGANIZATION -> Known.ORGANIZATION + PROJECT -> Known.PROJECT + EXPERIMENT -> Known.EXPERIMENT + DATASET -> Known.DATASET + PROMPT -> Known.PROMPT + PROMPT_SESSION -> Known.PROMPT_SESSION + GROUP -> Known.GROUP + ROLE -> Known.ROLE + ORG_MEMBER -> Known.ORG_MEMBER + PROJECT_LOG -> Known.PROJECT_LOG + ORG_PROJECT -> Known.ORG_PROJECT + else -> throw BraintrustInvalidDataException("Unknown AclObjectType: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AclObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclRetrieveParams.kt index 52819618..a591bf37 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AclRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an acl object by its id */ class AclRetrieveParams -constructor( +private constructor( private val aclId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Acl id */ fun aclId(): String = aclId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AclRetrieveParams && - this.aclId == other.aclId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - aclId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "AclRetrieveParams{aclId=$aclId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AclRetrieveParams]. + * + * The following fields are required: + * ```java + * .aclId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AclRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aclId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(aclRetrieveParams: AclRetrieveParams) = apply { - this.aclId = aclRetrieveParams.aclId - additionalQueryParams(aclRetrieveParams.additionalQueryParams) - additionalHeaders(aclRetrieveParams.additionalHeaders) + aclId = aclRetrieveParams.aclId + additionalHeaders = aclRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = aclRetrieveParams.additionalQueryParams.toBuilder() } /** Acl id */ fun aclId(aclId: String) = apply { this.aclId = aclId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [AclRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .aclId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AclRetrieveParams = AclRetrieveParams( - checkNotNull(aclId) { "`aclId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("aclId", aclId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AclRetrieveParams && aclId == other.aclId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aclId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AclRetrieveParams{aclId=$aclId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecret.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecret.kt deleted file mode 100644 index e7d4df58..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecret.kt +++ /dev/null @@ -1,305 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = AISecret.Builder::class) -@NoAutoDetect -class AISecret -private constructor( - private val id: JsonField, - private val created: JsonField, - private val orgId: JsonField, - private val name: JsonField, - private val type: JsonField, - private val metadata: JsonField, - private val previewSecret: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the AI secret */ - fun id(): String = id.getRequired("id") - - /** Date of AI secret creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** Unique identifier for the organization */ - fun orgId(): String = orgId.getRequired("org_id") - - /** Name of the AI secret */ - fun name(): String = name.getRequired("name") - - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - fun previewSecret(): Optional = - Optional.ofNullable(previewSecret.getNullable("preview_secret")) - - /** Unique identifier for the AI secret */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Date of AI secret creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Unique identifier for the organization */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId - - /** Name of the AI secret */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - @JsonProperty("preview_secret") @ExcludeMissing fun _previewSecret() = previewSecret - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): AISecret = apply { - if (!validated) { - id() - created() - orgId() - name() - type() - metadata().map { it.validate() } - previewSecret() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AISecret && - this.id == other.id && - this.created == other.created && - this.orgId == other.orgId && - this.name == other.name && - this.type == other.type && - this.metadata == other.metadata && - this.previewSecret == other.previewSecret && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - created, - orgId, - name, - type, - metadata, - previewSecret, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AISecret{id=$id, created=$created, orgId=$orgId, name=$name, type=$type, metadata=$metadata, previewSecret=$previewSecret, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var id: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var previewSecret: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(aiSecret: AISecret) = apply { - this.id = aiSecret.id - this.created = aiSecret.created - this.orgId = aiSecret.orgId - this.name = aiSecret.name - this.type = aiSecret.type - this.metadata = aiSecret.metadata - this.previewSecret = aiSecret.previewSecret - additionalProperties(aiSecret.additionalProperties) - } - - /** Unique identifier for the AI secret */ - fun id(id: String) = id(JsonField.of(id)) - - /** Unique identifier for the AI secret */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Date of AI secret creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** Date of AI secret creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** Unique identifier for the organization */ - fun orgId(orgId: String) = orgId(JsonField.of(orgId)) - - /** Unique identifier for the organization */ - @JsonProperty("org_id") - @ExcludeMissing - fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - - /** Name of the AI secret */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the AI secret */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - fun type(type: String) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - fun previewSecret(previewSecret: String) = previewSecret(JsonField.of(previewSecret)) - - @JsonProperty("preview_secret") - @ExcludeMissing - fun previewSecret(previewSecret: JsonField) = apply { - this.previewSecret = previewSecret - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): AISecret = - AISecret( - id, - created, - orgId, - name, - type, - metadata, - previewSecret, - additionalProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretCreateParams.kt index 779156e8..1fbb51db 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretCreateParams.kt @@ -3,416 +3,744 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new ai_secret. If there is an existing ai_secret with the same name as the one specified + * in the request, will return the existing ai_secret unmodified + */ class AiSecretCreateParams -constructor( - private val name: String, - private val metadata: Metadata?, - private val orgName: String?, - private val secret: String?, - private val type: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - fun secret(): Optional = Optional.ofNullable(secret) - - fun type(): Optional = Optional.ofNullable(type) - - @JvmSynthetic - internal fun getBody(): AiSecretCreateBody { - return AiSecretCreateBody( - name, - metadata, - orgName, - secret, - type, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * Secret value. If omitted in a PUT request, the existing secret value will be left intact, not + * replaced with null. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun secret(): Optional = body.secret() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = body.type() + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + /** + * Returns the raw JSON value of [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _secret(): JsonField = body._secret() + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _type(): JsonField = body._type() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = AiSecretCreateBody.Builder::class) @NoAutoDetect - class AiSecretCreateBody - internal constructor( - private val name: String?, - private val metadata: Metadata?, - private val orgName: String?, - private val secret: String?, - private val type: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonProperty("secret") + @ExcludeMissing + private val secret: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the AI secret */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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") - @JsonProperty("metadata") fun metadata(): Metadata? = metadata + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("org_name") fun orgName(): String? = orgName + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) /** * Secret value. If omitted in a PUT request, the existing secret value will be left intact, * not replaced with null. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun secret(): Optional = Optional.ofNullable(secret.getNullable("secret")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("secret") fun secret(): String? = secret + fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - @JsonProperty("type") fun type(): String? = type + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName + + /** + * Returns the raw JSON value of [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("secret") @ExcludeMissing fun _secret(): JsonField = secret + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AiSecretCreateBody && - this.name == other.name && - this.metadata == other.metadata && - this.orgName == other.orgName && - this.secret == other.secret && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - metadata, - orgName, - secret, - type, - additionalProperties, - ) - } - return hashCode + name() + metadata().ifPresent { it.validate() } + orgName() + secret() + type() + validated = true } - override fun toString() = - "AiSecretCreateBody{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var metadata: Metadata? = null - private var orgName: String? = null - private var secret: String? = null - private var type: String? = null + private var name: JsonField? = null + private var metadata: JsonField = JsonMissing.of() + private var orgName: JsonField = JsonMissing.of() + private var secret: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aiSecretCreateBody: AiSecretCreateBody) = apply { - this.name = aiSecretCreateBody.name - this.metadata = aiSecretCreateBody.metadata - this.orgName = aiSecretCreateBody.orgName - this.secret = aiSecretCreateBody.secret - this.type = aiSecretCreateBody.type - additionalProperties(aiSecretCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + metadata = body.metadata + orgName = body.orgName + secret = body.secret + type = body.type + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the AI secret */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + /** + * 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 } + + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } /** * Secret value. If omitted in a PUT request, the existing secret value will be left * intact, not replaced with null. */ - @JsonProperty("secret") fun secret(secret: String) = apply { this.secret = secret } + fun secret(secret: String?) = secret(JsonField.ofNullable(secret)) + + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) + + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun secret(secret: JsonField) = apply { this.secret = secret } - @JsonProperty("type") fun type(type: String) = apply { this.type = type } + fun type(type: String?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AiSecretCreateBody = - AiSecretCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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), metadata, orgName, secret, type, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && metadata == other.metadata && orgName == other.orgName && secret == other.secret && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AiSecretCreateParams && - this.name == other.name && - this.metadata == other.metadata && - this.orgName == other.orgName && - this.secret == other.secret && - this.type == other.type && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, metadata, orgName, secret, type, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - metadata, - orgName, - secret, - type, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AiSecretCreateParams{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var metadata: Metadata? = null - private var orgName: String? = null - private var secret: String? = null - private var type: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(aiSecretCreateParams: AiSecretCreateParams) = apply { - this.name = aiSecretCreateParams.name - this.metadata = aiSecretCreateParams.metadata - this.orgName = aiSecretCreateParams.orgName - this.secret = aiSecretCreateParams.secret - this.type = aiSecretCreateParams.type - additionalQueryParams(aiSecretCreateParams.additionalQueryParams) - additionalHeaders(aiSecretCreateParams.additionalHeaders) - additionalBodyProperties(aiSecretCreateParams.additionalBodyProperties) + body = aiSecretCreateParams.body.toBuilder() + additionalHeaders = aiSecretCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretCreateParams.additionalQueryParams.toBuilder() } /** Name of the AI secret */ - fun name(name: String) = apply { this.name = 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) } + + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } /** * Secret value. If omitted in a PUT request, the existing secret value will be left intact, * not replaced with null. */ - fun secret(secret: String) = apply { this.secret = secret } + fun secret(secret: String?) = apply { body.secret(secret) } - fun type(type: String) = apply { this.type = type } + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun secret(secret: JsonField) = apply { body.secret(secret) } + + fun type(type: String?) = apply { body.type(type) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { body.type(type) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [AiSecretCreateParams]. + * + * 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(): AiSecretCreateParams = AiSecretCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - metadata, - orgName, - secret, - type, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretDeleteParams.kt index 6ddecb7f..2fa3533f 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an ai_secret object by its id */ class AiSecretDeleteParams -constructor( +private constructor( private val aiSecretId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** AiSecret id */ fun aiSecretId(): String = aiSecretId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AiSecretDeleteParams && - this.aiSecretId == other.aiSecretId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - aiSecretId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "AiSecretDeleteParams{aiSecretId=$aiSecretId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretDeleteParams]. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aiSecretId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(aiSecretDeleteParams: AiSecretDeleteParams) = apply { - this.aiSecretId = aiSecretDeleteParams.aiSecretId - additionalQueryParams(aiSecretDeleteParams.additionalQueryParams) - additionalHeaders(aiSecretDeleteParams.additionalHeaders) - additionalBodyProperties(aiSecretDeleteParams.additionalBodyProperties) + aiSecretId = aiSecretDeleteParams.aiSecretId + additionalHeaders = aiSecretDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = aiSecretDeleteParams.additionalBodyProperties.toMutableMap() } /** AiSecret id */ fun aiSecretId(aiSecretId: String) = apply { this.aiSecretId = aiSecretId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [AiSecretDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AiSecretDeleteParams = AiSecretDeleteParams( - checkNotNull(aiSecretId) { "`aiSecretId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("aiSecretId", aiSecretId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretDeleteParams && aiSecretId == other.aiSecretId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "AiSecretDeleteParams{aiSecretId=$aiSecretId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParams.kt index 837d68ed..40ba1a94 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParams.kt @@ -3,276 +3,458 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Delete a single ai_secret */ class AiSecretFindAndDeleteParams -constructor( - private val name: String, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): AiSecretFindAndDeleteBody { - return AiSecretFindAndDeleteBody( - name, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = AiSecretFindAndDeleteBody.Builder::class) @NoAutoDetect - class AiSecretFindAndDeleteBody - internal constructor( - private val name: String?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the AI secret */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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") /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AiSecretFindAndDeleteBody && - this.name == other.name && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties + name() + orgName() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - orgName, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AiSecretFindAndDeleteBody{name=$name, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null + private var name: JsonField? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aiSecretFindAndDeleteBody: AiSecretFindAndDeleteBody) = apply { - this.name = aiSecretFindAndDeleteBody.name - this.orgName = aiSecretFindAndDeleteBody.orgName - additionalProperties(aiSecretFindAndDeleteBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the AI secret */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AiSecretFindAndDeleteBody = - AiSecretFindAndDeleteBody( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * 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), orgName, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AiSecretFindAndDeleteParams && - this.name == other.name && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AiSecretFindAndDeleteParams{name=$name, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretFindAndDeleteParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretFindAndDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(aiSecretFindAndDeleteParams: AiSecretFindAndDeleteParams) = apply { - this.name = aiSecretFindAndDeleteParams.name - this.orgName = aiSecretFindAndDeleteParams.orgName - additionalQueryParams(aiSecretFindAndDeleteParams.additionalQueryParams) - additionalHeaders(aiSecretFindAndDeleteParams.additionalHeaders) - additionalBodyProperties(aiSecretFindAndDeleteParams.additionalBodyProperties) + body = aiSecretFindAndDeleteParams.body.toBuilder() + additionalHeaders = aiSecretFindAndDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretFindAndDeleteParams.additionalQueryParams.toBuilder() } /** Name of the AI secret */ - fun name(name: String) = apply { this.name = 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) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [AiSecretFindAndDeleteParams]. + * + * 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(): AiSecretFindAndDeleteParams = AiSecretFindAndDeleteParams( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretFindAndDeleteParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretFindAndDeleteParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPage.kt index 2adbb611..af920955 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.AiSecretService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most + * recently-created ai_secrets coming first + */ class AiSecretListPage private constructor( private val aiSecretsService: AiSecretService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is AiSecretListPage && - this.aiSecretsService == other.aiSecretsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is AiSecretListPage && aiSecretsService == other.aiSecretsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - aiSecretsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretsService, params, response) /* spotless:on */ override fun toString() = "AiSecretListPage{aiSecretsService=$aiSecretsService, params=$params, response=$response}" @@ -87,23 +84,18 @@ private constructor( @JvmStatic fun of(aiSecretsService: AiSecretService, params: AiSecretListParams, response: Response) = - AiSecretListPage( - aiSecretsService, - params, - response, - ) + AiSecretListPage(aiSecretsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -113,11 +105,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -127,20 +123,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "AiSecretListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [AiSecretListPage]. */ @JvmStatic fun builder() = Builder() } @@ -157,22 +150,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: AiSecretListPage, - ) : Iterable { + class AutoPager(private val firstPage: AiSecretListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -181,7 +174,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPageAsync.kt index af3a1365..441b79ce 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.AiSecretServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most + * recently-created ai_secrets coming first + */ class AiSecretListPageAsync private constructor( private val aiSecretsService: AiSecretServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is AiSecretListPageAsync && - this.aiSecretsService == other.aiSecretsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is AiSecretListPageAsync && aiSecretsService == other.aiSecretsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - aiSecretsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretsService, params, response) /* spotless:on */ override fun toString() = "AiSecretListPageAsync{aiSecretsService=$aiSecretsService, params=$params, response=$response}" @@ -92,25 +88,19 @@ private constructor( fun of( aiSecretsService: AiSecretServiceAsync, params: AiSecretListParams, - response: Response - ) = - AiSecretListPageAsync( - aiSecretsService, - params, - response, - ) + response: Response, + ) = AiSecretListPageAsync(aiSecretsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +110,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +128,19 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "AiSecretListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +157,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: AiSecretListPageAsync, - ) { + class AutoPager(private val firstPage: AiSecretListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (AISecret) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +186,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListParams.kt index d9170848..4359719a 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most + * recently-created ai_secrets coming first + */ class AiSecretListParams -constructor( +private constructor( private val aiSecretName: String?, private val aiSecretType: AiSecretType?, private val endingBefore: String?, @@ -29,87 +35,98 @@ constructor( private val limit: Long?, private val orgName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Name of the ai_secret to search for */ fun aiSecretName(): Optional = Optional.ofNullable(aiSecretName) fun aiSecretType(): Optional = Optional.ofNullable(aiSecretType) + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.aiSecretName?.let { params.put("ai_secret_name", listOf(it.toString())) } - this.aiSecretType?.let { params.put("ai_secret_type", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AiSecretListParams && - this.aiSecretName == other.aiSecretName && - this.aiSecretType == other.aiSecretType && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - aiSecretName, - aiSecretType, - endingBefore, - ids, - limit, - orgName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "AiSecretListParams{aiSecretName=$aiSecretName, aiSecretType=$aiSecretType, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + aiSecretName?.let { put("ai_secret_name", it) } + aiSecretType?.accept( + object : AiSecretType.Visitor { + override fun visitString(string: String) { + put("ai_secret_type", string) + } + + override fun visitStrings(strings: List) { + put("ai_secret_type", strings.joinToString(",")) + } + } + ) + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): AiSecretListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AiSecretListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aiSecretName: String? = null private var aiSecretType: AiSecretType? = null @@ -118,34 +135,40 @@ constructor( private var limit: Long? = null private var orgName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(aiSecretListParams: AiSecretListParams) = apply { - this.aiSecretName = aiSecretListParams.aiSecretName - this.aiSecretType = aiSecretListParams.aiSecretType - this.endingBefore = aiSecretListParams.endingBefore - this.ids = aiSecretListParams.ids - this.limit = aiSecretListParams.limit - this.orgName = aiSecretListParams.orgName - this.startingAfter = aiSecretListParams.startingAfter - additionalQueryParams(aiSecretListParams.additionalQueryParams) - additionalHeaders(aiSecretListParams.additionalHeaders) + aiSecretName = aiSecretListParams.aiSecretName + aiSecretType = aiSecretListParams.aiSecretType + endingBefore = aiSecretListParams.endingBefore + ids = aiSecretListParams.ids + limit = aiSecretListParams.limit + orgName = aiSecretListParams.orgName + startingAfter = aiSecretListParams.startingAfter + additionalHeaders = aiSecretListParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretListParams.additionalQueryParams.toBuilder() } /** Name of the ai_secret to search for */ - fun aiSecretName(aiSecretName: String) = apply { this.aiSecretName = aiSecretName } + fun aiSecretName(aiSecretName: String?) = apply { this.aiSecretName = aiSecretName } - fun aiSecretType(aiSecretType: AiSecretType) = apply { this.aiSecretType = aiSecretType } + /** Alias for calling [Builder.aiSecretName] with `aiSecretName.orElse(null)`. */ + fun aiSecretName(aiSecretName: Optional) = aiSecretName(aiSecretName.getOrNull()) - fun aiSecretType(string: String) = apply { - this.aiSecretType = AiSecretType.ofString(string) - } + fun aiSecretType(aiSecretType: AiSecretType?) = apply { this.aiSecretType = aiSecretType } - fun aiSecretType(strings: List) = apply { - this.aiSecretType = AiSecretType.ofStrings(strings) - } + /** Alias for calling [Builder.aiSecretType] with `aiSecretType.orElse(null)`. */ + fun aiSecretType(aiSecretType: Optional) = + aiSecretType(aiSecretType.getOrNull()) + + /** Alias for calling [aiSecretType] with `AiSecretType.ofString(string)`. */ + fun aiSecretType(string: String) = aiSecretType(AiSecretType.ofString(string)) + + /** Alias for calling [aiSecretType] with `AiSecretType.ofStrings(strings)`. */ + fun aiSecretTypeOfStrings(strings: List) = + aiSecretType(AiSecretType.ofStrings(strings)) /** * Pagination cursor id. @@ -154,31 +177,44 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** * Pagination cursor id. @@ -187,48 +223,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [AiSecretListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): AiSecretListParams = AiSecretListParams( aiSecretName, @@ -238,8 +341,8 @@ constructor( limit, orgName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -252,8 +355,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -276,37 +377,23 @@ constructor( } } - fun validate(): AiSecretType = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown AiSecretType: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is AiSecretType && - this.string == other.string && - this.strings == other.strings + return /* spotless:off */ other is AiSecretType && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "AiSecretType{string=$string}" strings != null -> "AiSecretType{strings=$strings}" _json != null -> "AiSecretType{_unknown=$_json}" else -> throw IllegalStateException("Invalid AiSecretType") } - } companion object { @@ -315,21 +402,36 @@ constructor( @JvmStatic fun ofStrings(strings: List) = AiSecretType(strings = strings) } + /** + * An interface that defines how to map each variant of [AiSecretType] to a value of type + * [T]. + */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [AiSecretType] to a value of type [T]. + * + * An instance of [AiSecretType] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown AiSecretType: $json") } } - class Deserializer : BaseDeserializer(AiSecretType::class) { + internal class Deserializer : BaseDeserializer(AiSecretType::class) { override fun ObjectCodec.deserialize(node: JsonNode): AiSecretType { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return AiSecretType(string = it, _json = json) } @@ -341,12 +443,12 @@ constructor( } } - class Serializer : BaseSerializer(AiSecretType::class) { + internal class Serializer : BaseSerializer(AiSecretType::class) { override fun serialize( value: AiSecretType, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -358,6 +460,10 @@ constructor( } } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -367,8 +473,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -391,35 +495,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -428,21 +520,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -454,12 +557,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -470,4 +573,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretListParams && aiSecretName == other.aiSecretName && aiSecretType == other.aiSecretType && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretName, aiSecretType, endingBefore, ids, limit, orgName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretListParams{aiSecretName=$aiSecretName, aiSecretType=$aiSecretType, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretReplaceParams.kt index ab2ecf44..9a5a51dd 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretReplaceParams.kt @@ -3,416 +3,744 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace ai_secret. If there is an existing ai_secret with the same name as the one + * specified in the request, will replace the existing ai_secret with the provided fields + */ class AiSecretReplaceParams -constructor( - private val name: String, - private val metadata: Metadata?, - private val orgName: String?, - private val secret: String?, - private val type: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - fun secret(): Optional = Optional.ofNullable(secret) - - fun type(): Optional = Optional.ofNullable(type) - - @JvmSynthetic - internal fun getBody(): AiSecretReplaceBody { - return AiSecretReplaceBody( - name, - metadata, - orgName, - secret, - type, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * Secret value. If omitted in a PUT request, the existing secret value will be left intact, not + * replaced with null. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun secret(): Optional = body.secret() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = body.type() + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + /** + * Returns the raw JSON value of [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _secret(): JsonField = body._secret() + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _type(): JsonField = body._type() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = AiSecretReplaceBody.Builder::class) @NoAutoDetect - class AiSecretReplaceBody - internal constructor( - private val name: String?, - private val metadata: Metadata?, - private val orgName: String?, - private val secret: String?, - private val type: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonProperty("secret") + @ExcludeMissing + private val secret: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the AI secret */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException 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") - @JsonProperty("metadata") fun metadata(): Metadata? = metadata + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("org_name") fun orgName(): String? = orgName + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) /** * Secret value. If omitted in a PUT request, the existing secret value will be left intact, * not replaced with null. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun secret(): Optional = Optional.ofNullable(secret.getNullable("secret")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("secret") fun secret(): String? = secret + fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - @JsonProperty("type") fun type(): String? = type + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName + + /** + * Returns the raw JSON value of [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("secret") @ExcludeMissing fun _secret(): JsonField = secret + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AiSecretReplaceBody && - this.name == other.name && - this.metadata == other.metadata && - this.orgName == other.orgName && - this.secret == other.secret && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - metadata, - orgName, - secret, - type, - additionalProperties, - ) - } - return hashCode + name() + metadata().ifPresent { it.validate() } + orgName() + secret() + type() + validated = true } - override fun toString() = - "AiSecretReplaceBody{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var metadata: Metadata? = null - private var orgName: String? = null - private var secret: String? = null - private var type: String? = null + private var name: JsonField? = null + private var metadata: JsonField = JsonMissing.of() + private var orgName: JsonField = JsonMissing.of() + private var secret: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aiSecretReplaceBody: AiSecretReplaceBody) = apply { - this.name = aiSecretReplaceBody.name - this.metadata = aiSecretReplaceBody.metadata - this.orgName = aiSecretReplaceBody.orgName - this.secret = aiSecretReplaceBody.secret - this.type = aiSecretReplaceBody.type - additionalProperties(aiSecretReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + metadata = body.metadata + orgName = body.orgName + secret = body.secret + type = body.type + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the AI secret */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + /** + * 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 } + + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } /** * Secret value. If omitted in a PUT request, the existing secret value will be left * intact, not replaced with null. */ - @JsonProperty("secret") fun secret(secret: String) = apply { this.secret = secret } + fun secret(secret: String?) = secret(JsonField.ofNullable(secret)) + + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) + + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun secret(secret: JsonField) = apply { this.secret = secret } - @JsonProperty("type") fun type(type: String) = apply { this.type = type } + fun type(type: String?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AiSecretReplaceBody = - AiSecretReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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), metadata, orgName, secret, type, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && metadata == other.metadata && orgName == other.orgName && secret == other.secret && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AiSecretReplaceParams && - this.name == other.name && - this.metadata == other.metadata && - this.orgName == other.orgName && - this.secret == other.secret && - this.type == other.type && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, metadata, orgName, secret, type, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - metadata, - orgName, - secret, - type, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AiSecretReplaceParams{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, metadata=$metadata, orgName=$orgName, secret=$secret, type=$type, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretReplaceParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var metadata: Metadata? = null - private var orgName: String? = null - private var secret: String? = null - private var type: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(aiSecretReplaceParams: AiSecretReplaceParams) = apply { - this.name = aiSecretReplaceParams.name - this.metadata = aiSecretReplaceParams.metadata - this.orgName = aiSecretReplaceParams.orgName - this.secret = aiSecretReplaceParams.secret - this.type = aiSecretReplaceParams.type - additionalQueryParams(aiSecretReplaceParams.additionalQueryParams) - additionalHeaders(aiSecretReplaceParams.additionalHeaders) - additionalBodyProperties(aiSecretReplaceParams.additionalBodyProperties) + body = aiSecretReplaceParams.body.toBuilder() + additionalHeaders = aiSecretReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretReplaceParams.additionalQueryParams.toBuilder() } /** Name of the AI secret */ - fun name(name: String) = apply { this.name = 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) } + + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the AI Secret belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } /** * Secret value. If omitted in a PUT request, the existing secret value will be left intact, * not replaced with null. */ - fun secret(secret: String) = apply { this.secret = secret } + fun secret(secret: String?) = apply { body.secret(secret) } - fun type(type: String) = apply { this.type = type } + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun secret(secret: JsonField) = apply { body.secret(secret) } + + fun type(type: String?) = apply { body.type(type) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { body.type(type) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [AiSecretReplaceParams]. + * + * 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(): AiSecretReplaceParams = AiSecretReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - metadata, - orgName, - secret, - type, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParams.kt index b0e59f6d..7ff996d2 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an ai_secret object by its id */ class AiSecretRetrieveParams -constructor( +private constructor( private val aiSecretId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** AiSecret id */ fun aiSecretId(): String = aiSecretId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AiSecretRetrieveParams && - this.aiSecretId == other.aiSecretId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - aiSecretId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "AiSecretRetrieveParams{aiSecretId=$aiSecretId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretRetrieveParams]. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aiSecretId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(aiSecretRetrieveParams: AiSecretRetrieveParams) = apply { - this.aiSecretId = aiSecretRetrieveParams.aiSecretId - additionalQueryParams(aiSecretRetrieveParams.additionalQueryParams) - additionalHeaders(aiSecretRetrieveParams.additionalHeaders) + aiSecretId = aiSecretRetrieveParams.aiSecretId + additionalHeaders = aiSecretRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretRetrieveParams.additionalQueryParams.toBuilder() } /** AiSecret id */ fun aiSecretId(aiSecretId: String) = apply { this.aiSecretId = aiSecretId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [AiSecretRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AiSecretRetrieveParams = AiSecretRetrieveParams( - checkNotNull(aiSecretId) { "`aiSecretId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("aiSecretId", aiSecretId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AiSecretRetrieveParams && aiSecretId == other.aiSecretId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretRetrieveParams{aiSecretId=$aiSecretId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretUpdateParams.kt index 4973300d..751a2ce2 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/AiSecretUpdateParams.kt @@ -3,53 +3,106 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update an ai_secret object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ class AiSecretUpdateParams -constructor( +private constructor( private val aiSecretId: String, - private val metadata: Metadata?, - private val name: String?, - private val secret: String?, - private val type: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** AiSecret id */ fun aiSecretId(): String = aiSecretId - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun name(): Optional = Optional.ofNullable(name) - - fun secret(): Optional = Optional.ofNullable(secret) - - fun type(): Optional = Optional.ofNullable(type) - - @JvmSynthetic - internal fun getBody(): AiSecretUpdateBody { - return AiSecretUpdateBody( - metadata, - name, - secret, - type, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun secret(): Optional = body.secret() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = body.type() + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * 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 [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _secret(): JsonField = body._secret() + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _type(): JsonField = body._type() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -58,330 +111,548 @@ constructor( } } - @JsonDeserialize(builder = AiSecretUpdateBody.Builder::class) @NoAutoDetect - class AiSecretUpdateBody - internal constructor( - private val metadata: Metadata?, - private val name: String?, - private val secret: String?, - private val type: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("secret") + @ExcludeMissing + private val secret: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - @JsonProperty("metadata") fun metadata(): Metadata? = metadata - - /** Name of the AI secret */ - @JsonProperty("name") fun name(): String? = name - - @JsonProperty("secret") fun secret(): String? = secret - - @JsonProperty("type") fun type(): String? = type + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Name of the AI secret + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun secret(): Optional = Optional.ofNullable(secret.getNullable("secret")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun type(): Optional = Optional.ofNullable(type.getNullable("type")) + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * 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 [secret]. + * + * Unlike [secret], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("secret") @ExcludeMissing fun _secret(): JsonField = secret + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is AiSecretUpdateBody && - this.metadata == other.metadata && - this.name == other.name && - this.secret == other.secret && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - metadata, - name, - secret, - type, - additionalProperties, - ) - } - return hashCode + metadata().ifPresent { it.validate() } + name() + secret() + type() + validated = true } - override fun toString() = - "AiSecretUpdateBody{metadata=$metadata, name=$name, secret=$secret, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var metadata: Metadata? = null - private var name: String? = null - private var secret: String? = null - private var type: String? = null + private var metadata: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var secret: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(aiSecretUpdateBody: AiSecretUpdateBody) = apply { - this.metadata = aiSecretUpdateBody.metadata - this.name = aiSecretUpdateBody.name - this.secret = aiSecretUpdateBody.secret - this.type = aiSecretUpdateBody.type - additionalProperties(aiSecretUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + metadata = body.metadata + name = body.name + secret = body.secret + type = body.type + additionalProperties = body.additionalProperties.toMutableMap() } - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) - /** Name of the AI secret */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) - @JsonProperty("secret") fun secret(secret: String) = apply { this.secret = secret } + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - @JsonProperty("type") fun type(type: String) = apply { this.type = type } + /** Name of the AI secret */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } + + fun secret(secret: String?) = secret(JsonField.ofNullable(secret)) + + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) + + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun secret(secret: JsonField) = apply { this.secret = secret } + + fun type(type: String?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): AiSecretUpdateBody = - AiSecretUpdateBody( - metadata, - name, - secret, - type, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(metadata, name, secret, type, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && metadata == other.metadata && name == other.name && secret == other.secret && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is AiSecretUpdateParams && - this.aiSecretId == other.aiSecretId && - this.metadata == other.metadata && - this.name == other.name && - this.secret == other.secret && - this.type == other.type && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(metadata, name, secret, type, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - aiSecretId, - metadata, - name, - secret, - type, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "AiSecretUpdateParams{aiSecretId=$aiSecretId, metadata=$metadata, name=$name, secret=$secret, type=$type, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{metadata=$metadata, name=$name, secret=$secret, type=$type, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AiSecretUpdateParams]. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [AiSecretUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var aiSecretId: String? = null - private var metadata: Metadata? = null - private var name: String? = null - private var secret: String? = null - private var type: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(aiSecretUpdateParams: AiSecretUpdateParams) = apply { - this.aiSecretId = aiSecretUpdateParams.aiSecretId - this.metadata = aiSecretUpdateParams.metadata - this.name = aiSecretUpdateParams.name - this.secret = aiSecretUpdateParams.secret - this.type = aiSecretUpdateParams.type - additionalQueryParams(aiSecretUpdateParams.additionalQueryParams) - additionalHeaders(aiSecretUpdateParams.additionalHeaders) - additionalBodyProperties(aiSecretUpdateParams.additionalBodyProperties) + aiSecretId = aiSecretUpdateParams.aiSecretId + body = aiSecretUpdateParams.body.toBuilder() + additionalHeaders = aiSecretUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = aiSecretUpdateParams.additionalQueryParams.toBuilder() } /** AiSecret id */ fun aiSecretId(aiSecretId: String) = apply { this.aiSecretId = aiSecretId } - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** Name of the AI secret */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } - fun secret(secret: String) = apply { this.secret = secret } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) - fun type(type: String) = apply { this.type = type } + /** + * 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) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + fun secret(secret: String?) = apply { body.secret(secret) } + + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) + + /** + * Sets [Builder.secret] to an arbitrary JSON value. + * + * You should usually call [Builder.secret] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun secret(secret: JsonField) = apply { body.secret(secret) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun type(type: String?) = apply { body.type(type) } + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { body.type(type) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [AiSecretUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .aiSecretId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AiSecretUpdateParams = AiSecretUpdateParams( - checkNotNull(aiSecretId) { "`aiSecretId` is required but was not set" }, - metadata, - name, - secret, - type, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("aiSecretId", aiSecretId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is AiSecretUpdateParams && aiSecretId == other.aiSecretId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(aiSecretId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "AiSecretUpdateParams{aiSecretId=$aiSecretId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKey.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKey.kt index 14eed088..6cebb35a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKey.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKey.kt @@ -7,211 +7,322 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ApiKey.Builder::class) @NoAutoDetect class ApiKey +@JsonCreator private constructor( - private val id: JsonField, - private val created: JsonField, - private val name: JsonField, - private val previewName: JsonField, - private val userId: JsonField, - private val orgId: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("preview_name") + @ExcludeMissing + private val previewName: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the api key */ + /** + * Unique identifier for the api key + * + * @throws BraintrustInvalidDataException 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") - /** Date of api key creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** Name of the api key */ + /** + * Name of the api key + * + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 previewName(): String = previewName.getRequired("preview_name") - /** Unique identifier for the user */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + /** + * Date of api key creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Unique identifier for the organization */ + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun orgId(): Optional = Optional.ofNullable(orgId.getNullable("org_id")) - /** Unique identifier for the api key */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Date of api key creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Name of the api key */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonProperty("preview_name") @ExcludeMissing fun _previewName() = previewName - - /** Unique identifier for the user */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * Unique identifier for the user + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Unique identifier for the organization */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + /** + * 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 [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 [previewName]. + * + * Unlike [previewName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preview_name") + @ExcludeMissing + fun _previewName(): JsonField = previewName + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ApiKey = apply { - if (!validated) { - id() - created() - name() - previewName() - userId() - orgId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ApiKey = apply { + if (validated) { + return@apply } - return other is ApiKey && - this.id == other.id && - this.created == other.created && - this.name == other.name && - this.previewName == other.previewName && - this.userId == other.userId && - this.orgId == other.orgId && - this.additionalProperties == other.additionalProperties + id() + name() + previewName() + created() + orgId() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - created, - name, - previewName, - userId, - orgId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ApiKey{id=$id, created=$created, name=$name, previewName=$previewName, userId=$userId, orgId=$orgId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ApiKey]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .previewName() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ApiKey]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var previewName: JsonField? = null private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var previewName: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() private var orgId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(apiKey: ApiKey) = apply { - this.id = apiKey.id - this.created = apiKey.created - this.name = apiKey.name - this.previewName = apiKey.previewName - this.userId = apiKey.userId - this.orgId = apiKey.orgId - additionalProperties(apiKey.additionalProperties) + id = apiKey.id + name = apiKey.name + previewName = apiKey.previewName + created = apiKey.created + orgId = apiKey.orgId + userId = apiKey.userId + additionalProperties = apiKey.additionalProperties.toMutableMap() } /** Unique identifier for the api key */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the api key */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Date of api key creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** Date of api key creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * 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 } /** Name of the api key */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the api key */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun previewName(previewName: String) = previewName(JsonField.of(previewName)) - @JsonProperty("preview_name") - @ExcludeMissing + /** + * Sets [Builder.previewName] to an arbitrary JSON value. + * + * You should usually call [Builder.previewName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun previewName(previewName: JsonField) = apply { this.previewName = previewName } - /** Unique identifier for the user */ - fun userId(userId: String) = userId(JsonField.of(userId)) - - /** Unique identifier for the user */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + /** Date of api key creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } /** Unique identifier for the organization */ - fun orgId(orgId: String) = orgId(JsonField.of(orgId)) + fun orgId(orgId: String?) = orgId(JsonField.ofNullable(orgId)) - /** Unique identifier for the organization */ - @JsonProperty("org_id") - @ExcludeMissing + /** Alias for calling [Builder.orgId] with `orgId.orElse(null)`. */ + fun orgId(orgId: Optional) = orgId(orgId.getOrNull()) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun orgId(orgId: JsonField) = apply { this.orgId = orgId } + /** Unique identifier for the user */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ApiKey]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .previewName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ApiKey = ApiKey( - id, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("previewName", previewName), created, - name, - previewName, - userId, orgId, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ApiKey && id == other.id && name == other.name && previewName == other.previewName && created == other.created && orgId == other.orgId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, previewName, created, orgId, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ApiKey{id=$id, name=$name, previewName=$previewName, created=$created, orgId=$orgId, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyCreateParams.kt index e5d0f3b9..f00eaec8 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyCreateParams.kt @@ -3,276 +3,461 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new api_key. It is possible to have multiple API keys with the same name. There is no + * de-duplication + */ class ApiKeyCreateParams -constructor( - private val name: String, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): ApiKeyCreateBody { - return ApiKeyCreateBody( - name, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the api key. Does not have to be unique + * + * @throws BraintrustInvalidDataException 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() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * API key belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ApiKeyCreateBody.Builder::class) @NoAutoDetect - class ApiKeyCreateBody - internal constructor( - private val name: String?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the api key. Does not have to be unique */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the api key. Does not have to be unique + * + * @throws BraintrustInvalidDataException 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") /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the API key belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ApiKeyCreateBody && - this.name == other.name && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties + name() + orgName() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - orgName, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ApiKeyCreateBody{name=$name, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null + private var name: JsonField? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(apiKeyCreateBody: ApiKeyCreateBody) = apply { - this.name = apiKeyCreateBody.name - this.orgName = apiKeyCreateBody.orgName - additionalProperties(apiKeyCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the api key. Does not have to be unique */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the API key belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ApiKeyCreateBody = - ApiKeyCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * 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), orgName, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ApiKeyCreateParams && - this.name == other.name && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ApiKeyCreateParams{name=$name, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ApiKeyCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ApiKeyCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(apiKeyCreateParams: ApiKeyCreateParams) = apply { - this.name = apiKeyCreateParams.name - this.orgName = apiKeyCreateParams.orgName - additionalQueryParams(apiKeyCreateParams.additionalQueryParams) - additionalHeaders(apiKeyCreateParams.additionalHeaders) - additionalBodyProperties(apiKeyCreateParams.additionalBodyProperties) + body = apiKeyCreateParams.body.toBuilder() + additionalHeaders = apiKeyCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = apiKeyCreateParams.additionalQueryParams.toBuilder() } /** Name of the api key. Does not have to be unique */ - fun name(name: String) = apply { this.name = 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) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the API key belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ApiKeyCreateParams]. + * + * 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(): ApiKeyCreateParams = ApiKeyCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ApiKeyCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ApiKeyCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParams.kt index 8b48e6d1..cc0903b2 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an api_key object by its id */ class ApiKeyDeleteParams -constructor( +private constructor( private val apiKeyId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** ApiKey id */ fun apiKeyId(): String = apiKeyId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ApiKeyDeleteParams && - this.apiKeyId == other.apiKeyId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - apiKeyId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "ApiKeyDeleteParams{apiKeyId=$apiKeyId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ApiKeyDeleteParams]. + * + * The following fields are required: + * ```java + * .apiKeyId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ApiKeyDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var apiKeyId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(apiKeyDeleteParams: ApiKeyDeleteParams) = apply { - this.apiKeyId = apiKeyDeleteParams.apiKeyId - additionalQueryParams(apiKeyDeleteParams.additionalQueryParams) - additionalHeaders(apiKeyDeleteParams.additionalHeaders) - additionalBodyProperties(apiKeyDeleteParams.additionalBodyProperties) + apiKeyId = apiKeyDeleteParams.apiKeyId + additionalHeaders = apiKeyDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = apiKeyDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = apiKeyDeleteParams.additionalBodyProperties.toMutableMap() } /** ApiKey id */ fun apiKeyId(apiKeyId: String) = apply { this.apiKeyId = apiKeyId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [ApiKeyDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .apiKeyId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ApiKeyDeleteParams = ApiKeyDeleteParams( - checkNotNull(apiKeyId) { "`apiKeyId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("apiKeyId", apiKeyId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ApiKeyDeleteParams && apiKeyId == other.apiKeyId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(apiKeyId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "ApiKeyDeleteParams{apiKeyId=$apiKeyId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPage.kt index 6369da73..4d1e410a 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ApiKeyService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all api_keys. The api_keys are sorted by creation date, with the most recently-created + * api_keys coming first + */ class ApiKeyListPage private constructor( private val apiKeysService: ApiKeyService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ApiKeyListPage && - this.apiKeysService == other.apiKeysService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ApiKeyListPage && apiKeysService == other.apiKeysService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - apiKeysService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(apiKeysService, params, response) /* spotless:on */ override fun toString() = "ApiKeyListPage{apiKeysService=$apiKeysService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(apiKeysService: ApiKeyService, params: ApiKeyListParams, response: Response) = - ApiKeyListPage( - apiKeysService, - params, - response, - ) + ApiKeyListPage(apiKeysService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ApiKeyListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ApiKeyListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ApiKeyListPage, - ) : Iterable { + class AutoPager(private val firstPage: ApiKeyListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPageAsync.kt index d8742552..28dc1058 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ApiKeyServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all api_keys. The api_keys are sorted by creation date, with the most recently-created + * api_keys coming first + */ class ApiKeyListPageAsync private constructor( private val apiKeysService: ApiKeyServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ApiKeyListPageAsync && - this.apiKeysService == other.apiKeysService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ApiKeyListPageAsync && apiKeysService == other.apiKeysService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - apiKeysService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(apiKeysService, params, response) /* spotless:on */ override fun toString() = "ApiKeyListPageAsync{apiKeysService=$apiKeysService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(apiKeysService: ApiKeyServiceAsync, params: ApiKeyListParams, response: Response) = - ApiKeyListPageAsync( - apiKeysService, - params, - response, - ) + ApiKeyListPageAsync(apiKeysService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ApiKeyListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ApiKeyListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ApiKeyListPageAsync, - ) { + class AutoPager(private val firstPage: ApiKeyListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (ApiKey) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListParams.kt index dbaf4340..03c6a458 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,91 +20,99 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all api_keys. The api_keys are sorted by creation date, with the most recently-created + * api_keys coming first + */ class ApiKeyListParams -constructor( +private constructor( private val apiKeyName: String?, private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val orgName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Name of the api_key to search for */ fun apiKeyName(): Optional = Optional.ofNullable(apiKeyName) + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.apiKeyName?.let { params.put("api_key_name", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ApiKeyListParams && - this.apiKeyName == other.apiKeyName && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - apiKeyName, - endingBefore, - ids, - limit, - orgName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ApiKeyListParams{apiKeyName=$apiKeyName, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + apiKeyName?.let { put("api_key_name", it) } + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): ApiKeyListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ApiKeyListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [ApiKeyListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var apiKeyName: String? = null private var endingBefore: String? = null @@ -111,23 +120,26 @@ constructor( private var limit: Long? = null private var orgName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(apiKeyListParams: ApiKeyListParams) = apply { - this.apiKeyName = apiKeyListParams.apiKeyName - this.endingBefore = apiKeyListParams.endingBefore - this.ids = apiKeyListParams.ids - this.limit = apiKeyListParams.limit - this.orgName = apiKeyListParams.orgName - this.startingAfter = apiKeyListParams.startingAfter - additionalQueryParams(apiKeyListParams.additionalQueryParams) - additionalHeaders(apiKeyListParams.additionalHeaders) + apiKeyName = apiKeyListParams.apiKeyName + endingBefore = apiKeyListParams.endingBefore + ids = apiKeyListParams.ids + limit = apiKeyListParams.limit + orgName = apiKeyListParams.orgName + startingAfter = apiKeyListParams.startingAfter + additionalHeaders = apiKeyListParams.additionalHeaders.toBuilder() + additionalQueryParams = apiKeyListParams.additionalQueryParams.toBuilder() } /** Name of the api_key to search for */ - fun apiKeyName(apiKeyName: String) = apply { this.apiKeyName = apiKeyName } + fun apiKeyName(apiKeyName: String?) = apply { this.apiKeyName = apiKeyName } + + /** Alias for calling [Builder.apiKeyName] with `apiKeyName.orElse(null)`. */ + fun apiKeyName(apiKeyName: Optional) = apiKeyName(apiKeyName.getOrNull()) /** * Pagination cursor id. @@ -136,31 +148,44 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** * Pagination cursor id. @@ -169,48 +194,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + 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 putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ApiKeyListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ApiKeyListParams = ApiKeyListParams( apiKeyName, @@ -219,11 +311,15 @@ constructor( limit, orgName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -233,8 +329,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -257,35 +351,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -294,21 +376,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -320,12 +413,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -336,4 +429,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ApiKeyListParams && apiKeyName == other.apiKeyName && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(apiKeyName, endingBefore, ids, limit, orgName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ApiKeyListParams{apiKeyName=$apiKeyName, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParams.kt index 836fb6f3..1a0b9c18 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an api_key object by its id */ class ApiKeyRetrieveParams -constructor( +private constructor( private val apiKeyId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** ApiKey id */ fun apiKeyId(): String = apiKeyId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ApiKeyRetrieveParams && - this.apiKeyId == other.apiKeyId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - apiKeyId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ApiKeyRetrieveParams{apiKeyId=$apiKeyId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ApiKeyRetrieveParams]. + * + * The following fields are required: + * ```java + * .apiKeyId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ApiKeyRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var apiKeyId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(apiKeyRetrieveParams: ApiKeyRetrieveParams) = apply { - this.apiKeyId = apiKeyRetrieveParams.apiKeyId - additionalQueryParams(apiKeyRetrieveParams.additionalQueryParams) - additionalHeaders(apiKeyRetrieveParams.additionalHeaders) + apiKeyId = apiKeyRetrieveParams.apiKeyId + additionalHeaders = apiKeyRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = apiKeyRetrieveParams.additionalQueryParams.toBuilder() } /** ApiKey id */ fun apiKeyId(apiKeyId: String) = apply { this.apiKeyId = apiKeyId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ApiKeyRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .apiKeyId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ApiKeyRetrieveParams = ApiKeyRetrieveParams( - checkNotNull(apiKeyId) { "`apiKeyId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("apiKeyId", apiKeyId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ApiKeyRetrieveParams && apiKeyId == other.apiKeyId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(apiKeyId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ApiKeyRetrieveParams{apiKeyId=$apiKeyId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImage.kt index 7bca54f3..5a3d774a 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImage.kt @@ -8,286 +8,359 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional -@JsonDeserialize(builder = ChatCompletionContentPartImage.Builder::class) @NoAutoDetect class ChatCompletionContentPartImage +@JsonCreator private constructor( - private val imageUrl: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("image_url") + @ExcludeMissing + private val imageUrl: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 imageUrl(): ImageUrl = imageUrl.getRequired("image_url") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("image_url") @ExcludeMissing fun _imageUrl() = imageUrl + /** + * Returns the raw JSON value of [imageUrl]. + * + * Unlike [imageUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("image_url") @ExcludeMissing fun _imageUrl(): JsonField = imageUrl - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ChatCompletionContentPartImage = apply { - if (!validated) { - imageUrl().validate() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ChatCompletionContentPartImage = apply { + if (validated) { + return@apply } - return other is ChatCompletionContentPartImage && - this.imageUrl == other.imageUrl && - this.type == other.type && - this.additionalProperties == other.additionalProperties + imageUrl().validate() + type() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - imageUrl, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ChatCompletionContentPartImage{imageUrl=$imageUrl, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [ChatCompletionContentPartImage]. + * + * The following fields are required: + * ```java + * .imageUrl() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ChatCompletionContentPartImage]. */ + class Builder internal constructor() { - private var imageUrl: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var imageUrl: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(chatCompletionContentPartImage: ChatCompletionContentPartImage) = apply { - this.imageUrl = chatCompletionContentPartImage.imageUrl - this.type = chatCompletionContentPartImage.type - additionalProperties(chatCompletionContentPartImage.additionalProperties) + imageUrl = chatCompletionContentPartImage.imageUrl + type = chatCompletionContentPartImage.type + additionalProperties = + chatCompletionContentPartImage.additionalProperties.toMutableMap() } fun imageUrl(imageUrl: ImageUrl) = imageUrl(JsonField.of(imageUrl)) - @JsonProperty("image_url") - @ExcludeMissing + /** + * Sets [Builder.imageUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.imageUrl] with a well-typed [ImageUrl] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun imageUrl(imageUrl: JsonField) = apply { this.imageUrl = imageUrl } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ChatCompletionContentPartImage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .imageUrl() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ChatCompletionContentPartImage = ChatCompletionContentPartImage( - imageUrl, - type, - additionalProperties.toUnmodifiable(), + checkRequired("imageUrl", imageUrl), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = ImageUrl.Builder::class) @NoAutoDetect class ImageUrl + @JsonCreator private constructor( - private val url: JsonField, - private val detail: JsonField, - private val additionalProperties: Map, + @JsonProperty("url") @ExcludeMissing private val url: JsonField = JsonMissing.of(), + @JsonProperty("detail") + @ExcludeMissing + private val detail: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 url(): String = url.getRequired("url") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun detail(): Optional = Optional.ofNullable(detail.getNullable("detail")) - @JsonProperty("url") @ExcludeMissing fun _url() = url + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url - @JsonProperty("detail") @ExcludeMissing fun _detail() = detail + /** + * Returns the raw JSON value of [detail]. + * + * Unlike [detail], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("detail") @ExcludeMissing fun _detail(): JsonField = detail @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ImageUrl = apply { - if (!validated) { - url() - detail() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ImageUrl = apply { + if (validated) { + return@apply } - return other is ImageUrl && - this.url == other.url && - this.detail == other.detail && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - url, - detail, - additionalProperties, - ) - } - return hashCode + url() + detail() + validated = true } - override fun toString() = - "ImageUrl{url=$url, detail=$detail, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ImageUrl]. + * + * The following fields are required: + * ```java + * .url() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ImageUrl]. */ + class Builder internal constructor() { - private var url: JsonField = JsonMissing.of() + private var url: JsonField? = null private var detail: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(imageUrl: ImageUrl) = apply { - this.url = imageUrl.url - this.detail = imageUrl.detail - additionalProperties(imageUrl.additionalProperties) + url = imageUrl.url + detail = imageUrl.detail + additionalProperties = imageUrl.additionalProperties.toMutableMap() } fun url(url: String) = url(JsonField.of(url)) - @JsonProperty("url") - @ExcludeMissing + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun url(url: JsonField) = apply { this.url = url } fun detail(detail: Detail) = detail(JsonField.of(detail)) - @JsonProperty("detail") - @ExcludeMissing + /** + * Sets [Builder.detail] to an arbitrary JSON value. + * + * You should usually call [Builder.detail] with a well-typed [Detail] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun detail(detail: JsonField) = apply { this.detail = detail } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ImageUrl]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ImageUrl = - ImageUrl( - url, - detail, - additionalProperties.toUnmodifiable(), - ) + ImageUrl(checkRequired("url", url), detail, additionalProperties.toImmutable()) } - class Detail - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + class Detail @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Detail && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val AUTO = Detail(JsonField.of("auto")) + @JvmField val AUTO = of("auto") - @JvmField val LOW = Detail(JsonField.of("low")) + @JvmField val LOW = of("low") - @JvmField val HIGH = Detail(JsonField.of("high")) + @JvmField val HIGH = of("high") @JvmStatic fun of(value: String) = Detail(JsonField.of(value)) } + /** An enum containing [Detail]'s known values. */ enum class Known { AUTO, LOW, HIGH, } + /** + * An enum containing [Detail]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Detail] 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 { AUTO, LOW, HIGH, + /** + * An enum member indicating that [Detail] 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) { AUTO -> Value.AUTO @@ -296,6 +369,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { AUTO -> Known.AUTO @@ -304,58 +386,159 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown Detail: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Detail && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is ImageUrl && url == other.url && detail == other.detail && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(url, detail, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "ImageUrl{url=$url, detail=$detail, additionalProperties=$additionalProperties}" + } + + class Type @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 IMAGE_URL = Type(JsonField.of("image_url")) + @JvmField val IMAGE_URL = of("image_url") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - IMAGE_URL, + IMAGE_URL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { IMAGE_URL, + /** An enum member indicating that [Type] 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) { IMAGE_URL -> Value.IMAGE_URL 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { IMAGE_URL -> Known.IMAGE_URL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ChatCompletionContentPartImage && imageUrl == other.imageUrl && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(imageUrl, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ChatCompletionContentPartImage{imageUrl=$imageUrl, type=$type, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartText.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartText.kt index 3df6a2a5..4d14c0cf 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartText.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartText.kt @@ -8,177 +8,265 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional -@JsonDeserialize(builder = ChatCompletionContentPartText.Builder::class) @NoAutoDetect class ChatCompletionContentPartText +@JsonCreator private constructor( - private val text: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonProperty("text") @ExcludeMissing private val text: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun text(): Optional = Optional.ofNullable(text.getNullable("text")) - fun type(): Type = type.getRequired("type") - - @JsonProperty("text") @ExcludeMissing fun _text() = text + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ChatCompletionContentPartText = apply { - if (!validated) { - text() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ChatCompletionContentPartText = apply { + if (validated) { + return@apply } - return other is ChatCompletionContentPartText && - this.text == other.text && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - text, - type, - additionalProperties, - ) - } - return hashCode + type() + text() + validated = true } - override fun toString() = - "ChatCompletionContentPartText{text=$text, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [ChatCompletionContentPartText]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ChatCompletionContentPartText]. */ + class Builder internal constructor() { + private var type: JsonField? = null private var text: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(chatCompletionContentPartText: ChatCompletionContentPartText) = apply { - this.text = chatCompletionContentPartText.text - this.type = chatCompletionContentPartText.type - additionalProperties(chatCompletionContentPartText.additionalProperties) + type = chatCompletionContentPartText.type + text = chatCompletionContentPartText.text + additionalProperties = chatCompletionContentPartText.additionalProperties.toMutableMap() } - fun text(text: String) = text(JsonField.of(text)) - - @JsonProperty("text") - @ExcludeMissing - fun text(text: JsonField) = apply { this.text = text } - fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } + fun text(text: String) = text(JsonField.of(text)) + + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun text(text: JsonField) = apply { this.text = text } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ChatCompletionContentPartText]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ChatCompletionContentPartText = ChatCompletionContentPartText( + checkRequired("type", type), text, - type, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val TEXT = Type(JsonField.of("text")) + @JvmField val TEXT = of("text") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - TEXT, + TEXT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { TEXT, + /** An enum member indicating that [Type] 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) { TEXT -> Value.TEXT 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { TEXT -> Known.TEXT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ChatCompletionContentPartText && type == other.type && text == other.text && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, text, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ChatCompletionContentPartText{type=$type, text=$text, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCall.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCall.kt index 5fa0d38a..6c3fcd98 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCall.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCall.kt @@ -8,305 +8,465 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects -@JsonDeserialize(builder = ChatCompletionMessageToolCall.Builder::class) @NoAutoDetect class ChatCompletionMessageToolCall +@JsonCreator private constructor( - private val id: JsonField, - private val function: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("function") + @ExcludeMissing + private val function: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 function(): Function = function.getRequired("function") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("id") @ExcludeMissing fun _id() = id - - @JsonProperty("function") @ExcludeMissing fun _function() = function - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 [function]. + * + * Unlike [function], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("function") @ExcludeMissing fun _function(): JsonField = function + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ChatCompletionMessageToolCall = apply { - if (!validated) { - id() - function().validate() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ChatCompletionMessageToolCall = apply { + if (validated) { + return@apply } - return other is ChatCompletionMessageToolCall && - this.id == other.id && - this.function == other.function && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - function, - type, - additionalProperties, - ) - } - return hashCode + id() + function().validate() + type() + validated = true } - override fun toString() = - "ChatCompletionMessageToolCall{id=$id, function=$function, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [ChatCompletionMessageToolCall]. + * + * The following fields are required: + * ```java + * .id() + * .function() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ChatCompletionMessageToolCall]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var function: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var function: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(chatCompletionMessageToolCall: ChatCompletionMessageToolCall) = apply { - this.id = chatCompletionMessageToolCall.id - this.function = chatCompletionMessageToolCall.function - this.type = chatCompletionMessageToolCall.type - additionalProperties(chatCompletionMessageToolCall.additionalProperties) + id = chatCompletionMessageToolCall.id + function = chatCompletionMessageToolCall.function + type = chatCompletionMessageToolCall.type + additionalProperties = chatCompletionMessageToolCall.additionalProperties.toMutableMap() } fun id(id: String) = id(JsonField.of(id)) - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } fun function(function: Function) = function(JsonField.of(function)) - @JsonProperty("function") - @ExcludeMissing + /** + * Sets [Builder.function] to an arbitrary JSON value. + * + * You should usually call [Builder.function] with a well-typed [Function] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun function(function: JsonField) = apply { this.function = function } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ChatCompletionMessageToolCall]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .function() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ChatCompletionMessageToolCall = ChatCompletionMessageToolCall( - id, - function, - type, - additionalProperties.toUnmodifiable(), + checkRequired("id", id), + checkRequired("function", function), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val arguments: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("arguments") + @ExcludeMissing + private val arguments: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 arguments(): String = arguments.getRequired("arguments") + /** + * @throws BraintrustInvalidDataException 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") - @JsonProperty("arguments") @ExcludeMissing fun _arguments() = arguments + /** + * Returns the raw JSON value of [arguments]. + * + * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("arguments") @ExcludeMissing fun _arguments(): JsonField = arguments - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - arguments() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.arguments == other.arguments && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - arguments, - name, - additionalProperties, - ) - } - return hashCode + arguments() + name() + validated = true } - override fun toString() = - "Function{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { - private var arguments: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var arguments: JsonField? = null + private var name: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.arguments = function.arguments - this.name = function.name - additionalProperties(function.additionalProperties) + arguments = function.arguments + name = function.name + additionalProperties = function.additionalProperties.toMutableMap() } fun arguments(arguments: String) = arguments(JsonField.of(arguments)) - @JsonProperty("arguments") - @ExcludeMissing + /** + * Sets [Builder.arguments] to an arbitrary JSON value. + * + * You should usually call [Builder.arguments] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun arguments(arguments: JsonField) = apply { this.arguments = arguments } fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( - arguments, - name, - additionalProperties.toUnmodifiable(), + checkRequired("arguments", arguments), + checkRequired("name", name), + additionalProperties.toImmutable(), ) } - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is Function && arguments == other.arguments && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(arguments, name, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + } + + class Type @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 FUNCTION = Type(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { FUNCTION, + /** An enum member indicating that [Type] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ChatCompletionMessageToolCall && id == other.id && function == other.function && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, function, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ChatCompletionMessageToolCall{id=$id, function=$function, type=$type, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CodeBundle.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CodeBundle.kt index d99a8cc3..56c5f85e 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CodeBundle.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CodeBundle.kt @@ -10,8 +10,10 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -26,158 +28,231 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = CodeBundle.Builder::class) @NoAutoDetect class CodeBundle +@JsonCreator private constructor( - private val runtimeContext: JsonField, - private val location: JsonField, - private val bundleId: JsonField, - private val preview: JsonField, - private val additionalProperties: Map, + @JsonProperty("bundle_id") + @ExcludeMissing + private val bundleId: JsonField = JsonMissing.of(), + @JsonProperty("location") + @ExcludeMissing + private val location: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = JsonMissing.of(), + @JsonProperty("preview") + @ExcludeMissing + private val preview: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") + /** + * @throws BraintrustInvalidDataException 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 bundleId(): String = bundleId.getRequired("bundle_id") + /** + * @throws BraintrustInvalidDataException 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 location(): Location = location.getRequired("location") - fun bundleId(): String = bundleId.getRequired("bundle_id") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") - /** A preview of the code */ + /** + * A preview of the code + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun preview(): Optional = Optional.ofNullable(preview.getNullable("preview")) - @JsonProperty("runtime_context") @ExcludeMissing fun _runtimeContext() = runtimeContext - - @JsonProperty("location") @ExcludeMissing fun _location() = location - - @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId() = bundleId + /** + * Returns the raw JSON value of [bundleId]. + * + * Unlike [bundleId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId(): JsonField = bundleId + + /** + * Returns the raw JSON value of [location]. + * + * Unlike [location], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("location") @ExcludeMissing fun _location(): JsonField = location + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("runtime_context") + @ExcludeMissing + fun _runtimeContext(): JsonField = runtimeContext - /** A preview of the code */ - @JsonProperty("preview") @ExcludeMissing fun _preview() = preview + /** + * Returns the raw JSON value of [preview]. + * + * Unlike [preview], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preview") @ExcludeMissing fun _preview(): JsonField = preview @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): CodeBundle = apply { - if (!validated) { - runtimeContext().validate() - location() - bundleId() - preview() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): CodeBundle = apply { + if (validated) { + return@apply } - return other is CodeBundle && - this.runtimeContext == other.runtimeContext && - this.location == other.location && - this.bundleId == other.bundleId && - this.preview == other.preview && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtimeContext, - location, - bundleId, - preview, - additionalProperties, - ) - } - return hashCode + bundleId() + location().validate() + runtimeContext().validate() + preview() + validated = true } - override fun toString() = - "CodeBundle{runtimeContext=$runtimeContext, location=$location, bundleId=$bundleId, preview=$preview, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [CodeBundle]. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [CodeBundle]. */ + class Builder internal constructor() { - private var runtimeContext: JsonField = JsonMissing.of() - private var location: JsonField = JsonMissing.of() - private var bundleId: JsonField = JsonMissing.of() + private var bundleId: JsonField? = null + private var location: JsonField? = null + private var runtimeContext: JsonField? = null private var preview: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(codeBundle: CodeBundle) = apply { - this.runtimeContext = codeBundle.runtimeContext - this.location = codeBundle.location - this.bundleId = codeBundle.bundleId - this.preview = codeBundle.preview - additionalProperties(codeBundle.additionalProperties) + bundleId = codeBundle.bundleId + location = codeBundle.location + runtimeContext = codeBundle.runtimeContext + preview = codeBundle.preview + additionalProperties = codeBundle.additionalProperties.toMutableMap() } - fun runtimeContext(runtimeContext: RuntimeContext) = - runtimeContext(JsonField.of(runtimeContext)) + fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - @JsonProperty("runtime_context") - @ExcludeMissing - fun runtimeContext(runtimeContext: JsonField) = apply { - this.runtimeContext = runtimeContext - } + /** + * Sets [Builder.bundleId] to an arbitrary JSON value. + * + * You should usually call [Builder.bundleId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun bundleId(bundleId: JsonField) = apply { this.bundleId = bundleId } fun location(location: Location) = location(JsonField.of(location)) - @JsonProperty("location") - @ExcludeMissing + /** + * Sets [Builder.location] to an arbitrary JSON value. + * + * You should usually call [Builder.location] with a well-typed [Location] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun location(location: JsonField) = apply { this.location = location } - fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) + /** Alias for calling [location] with `Location.ofExperiment(experiment)`. */ + fun location(experiment: Location.Experiment) = location(Location.ofExperiment(experiment)) - @JsonProperty("bundle_id") - @ExcludeMissing - fun bundleId(bundleId: JsonField) = apply { this.bundleId = bundleId } + /** Alias for calling [location] with `Location.ofFunction(function)`. */ + fun location(function: Location.Function) = location(Location.ofFunction(function)) - /** A preview of the code */ - fun preview(preview: String) = preview(JsonField.of(preview)) + fun runtimeContext(runtimeContext: RuntimeContext) = + runtimeContext(JsonField.of(runtimeContext)) + + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed [RuntimeContext] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun runtimeContext(runtimeContext: JsonField) = apply { + this.runtimeContext = runtimeContext + } /** A preview of the code */ - @JsonProperty("preview") - @ExcludeMissing + fun preview(preview: String?) = preview(JsonField.ofNullable(preview)) + + /** Alias for calling [Builder.preview] with `preview.orElse(null)`. */ + fun preview(preview: Optional) = preview(preview.getOrNull()) + + /** + * Sets [Builder.preview] to an arbitrary JSON value. + * + * You should usually call [Builder.preview] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun preview(preview: JsonField) = apply { this.preview = preview } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [CodeBundle]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): CodeBundle = CodeBundle( - runtimeContext, - location, - bundleId, + checkRequired("bundleId", bundleId), + checkRequired("location", location), + checkRequired("runtimeContext", runtimeContext), preview, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } @@ -190,8 +265,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun experiment(): Optional = Optional.ofNullable(experiment) fun function(): Optional = Optional.ofNullable(function) @@ -214,15 +287,25 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): Location = apply { - if (!validated) { - if (experiment == null && function == null) { - throw BraintrustInvalidDataException("Unknown Location: $_json") - } - experiment?.validate() - function?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitExperiment(experiment: Experiment) { + experiment.validate() + } + + override fun visitFunction(function: Function) { + function.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -230,23 +313,18 @@ private constructor( return true } - return other is Location && - this.experiment == other.experiment && - this.function == other.function + return /* spotless:off */ other is Location && experiment == other.experiment && function == other.function /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(experiment, function) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experiment, function) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { experiment != null -> "Location{experiment=$experiment}" function != null -> "Location{function=$function}" _json != null -> "Location{_unknown=$_json}" else -> throw IllegalStateException("Invalid Location") } - } companion object { @@ -255,21 +333,35 @@ private constructor( @JvmStatic fun ofFunction(function: Function) = Location(function = function) } + /** + * An interface that defines how to map each variant of [Location] to a value of type [T]. + */ interface Visitor { fun visitExperiment(experiment: Experiment): T fun visitFunction(function: Function): T + /** + * Maps an unknown variant of [Location] to a value of type [T]. + * + * An instance of [Location] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Location: $json") } } - class Deserializer : BaseDeserializer(Location::class) { + internal class Deserializer : BaseDeserializer(Location::class) { override fun ObjectCodec.deserialize(node: JsonNode): Location { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Location(experiment = it, _json = json) @@ -283,12 +375,12 @@ private constructor( } } - class Serializer : BaseSerializer(Location::class) { + internal class Serializer : BaseSerializer(Location::class) { override fun serialize( value: Location, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.experiment != null -> generator.writeObject(value.experiment) @@ -299,121 +391,165 @@ private constructor( } } - @JsonDeserialize(builder = Experiment.Builder::class) @NoAutoDetect class Experiment + @JsonCreator private constructor( - private val type: JsonField, - private val evalName: JsonField, - private val position: JsonField, - private val additionalProperties: Map, + @JsonProperty("eval_name") + @ExcludeMissing + private val evalName: JsonField = JsonMissing.of(), + @JsonProperty("position") + @ExcludeMissing + private val position: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") - + /** + * @throws BraintrustInvalidDataException 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 evalName(): String = evalName.getRequired("eval_name") + /** + * @throws BraintrustInvalidDataException 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 position(): Position = position.getRequired("position") - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("eval_name") @ExcludeMissing fun _evalName() = evalName + /** + * Returns the raw JSON value of [evalName]. + * + * Unlike [evalName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("eval_name") @ExcludeMissing fun _evalName(): JsonField = evalName + + /** + * Returns the raw JSON value of [position]. + * + * Unlike [position], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("position") + @ExcludeMissing + fun _position(): JsonField = position - @JsonProperty("position") @ExcludeMissing fun _position() = position + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Experiment = apply { - if (!validated) { - type() - evalName() - position() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Experiment = apply { + if (validated) { + return@apply } - return other is Experiment && - this.type == other.type && - this.evalName == other.evalName && - this.position == other.position && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - evalName, - position, - additionalProperties, - ) - } - return hashCode + evalName() + position().validate() + type() + validated = true } - override fun toString() = - "Experiment{type=$type, evalName=$evalName, position=$position, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Experiment]. + * + * The following fields are required: + * ```java + * .evalName() + * .position() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Experiment]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var evalName: JsonField = JsonMissing.of() - private var position: JsonField = JsonMissing.of() + private var evalName: JsonField? = null + private var position: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(experiment: Experiment) = apply { - this.type = experiment.type - this.evalName = experiment.evalName - this.position = experiment.position - additionalProperties(experiment.additionalProperties) + evalName = experiment.evalName + position = experiment.position + type = experiment.type + additionalProperties = experiment.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun evalName(evalName: String) = evalName(JsonField.of(evalName)) - @JsonProperty("eval_name") - @ExcludeMissing + /** + * Sets [Builder.evalName] to an arbitrary JSON value. + * + * You should usually call [Builder.evalName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun evalName(evalName: JsonField) = apply { this.evalName = evalName } fun position(position: Position) = position(JsonField.of(position)) - @JsonProperty("position") - @ExcludeMissing + /** + * Sets [Builder.position] to an arbitrary JSON value. + * + * You should usually call [Builder.position] with a well-typed [Position] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun position(position: JsonField) = apply { this.position = position } + /** Alias for calling [position] with `Position.ofType(type)`. */ + fun position(type: Position.Type) = position(Position.ofType(type)) + + /** Alias for calling [position] with `Position.ofScorer(scorer)`. */ + fun position(scorer: Position.Scorer) = position(Position.ofScorer(scorer)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -421,12 +557,34 @@ private constructor( 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 [Experiment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .evalName() + * .position() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Experiment = Experiment( - type, - evalName, - position, - additionalProperties.toUnmodifiable(), + checkRequired("evalName", evalName), + checkRequired("position", position), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } @@ -434,22 +592,20 @@ private constructor( @JsonSerialize(using = Position.Serializer::class) class Position private constructor( - private val task: Task? = null, + private val type: Type? = null, private val scorer: Scorer? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - - fun task(): Optional = Optional.ofNullable(task) + fun type(): Optional = Optional.ofNullable(type) fun scorer(): Optional = Optional.ofNullable(scorer) - fun isTask(): Boolean = task != null + fun isType(): Boolean = type != null fun isScorer(): Boolean = scorer != null - fun asTask(): Task = task.getOrThrow("task") + fun asType(): Type = type.getOrThrow("type") fun asScorer(): Scorer = scorer.getOrThrow("scorer") @@ -457,21 +613,31 @@ private constructor( fun accept(visitor: Visitor): T { return when { - task != null -> visitor.visitTask(task) + type != null -> visitor.visitType(type) scorer != null -> visitor.visitScorer(scorer) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Position = apply { - if (!validated) { - if (task == null && scorer == null) { - throw BraintrustInvalidDataException("Unknown Position: $_json") - } - task?.validate() - scorer?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitType(type: Type) { + type.validate() + } + + override fun visitScorer(scorer: Scorer) { + scorer.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -479,49 +645,59 @@ private constructor( return true } - return other is Position && - this.task == other.task && - this.scorer == other.scorer + return /* spotless:off */ other is Position && type == other.type && scorer == other.scorer /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(task, scorer) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(type, scorer) /* spotless:on */ - override fun toString(): String { - return when { - task != null -> "Position{task=$task}" + override fun toString(): String = + when { + type != null -> "Position{type=$type}" scorer != null -> "Position{scorer=$scorer}" _json != null -> "Position{_unknown=$_json}" else -> throw IllegalStateException("Invalid Position") } - } companion object { - @JvmStatic fun ofTask(task: Task) = Position(task = task) + @JvmStatic fun ofType(type: Type) = Position(type = type) @JvmStatic fun ofScorer(scorer: Scorer) = Position(scorer = scorer) } + /** + * An interface that defines how to map each variant of [Position] to a value of + * type [T]. + */ interface Visitor { - fun visitTask(task: Task): T + fun visitType(type: Type): T fun visitScorer(scorer: Scorer): T + /** + * Maps an unknown variant of [Position] to a value of type [T]. + * + * An instance of [Position] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Position: $json") } } - class Deserializer : BaseDeserializer(Position::class) { + internal class Deserializer : BaseDeserializer(Position::class) { override fun ObjectCodec.deserialize(node: JsonNode): Position { val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { it.validate() } + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Position(task = it, _json = json) + return Position(type = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { @@ -532,174 +708,771 @@ private constructor( } } - class Serializer : BaseSerializer(Position::class) { + internal class Serializer : BaseSerializer(Position::class) { override fun serialize( value: Position, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.task != null -> generator.writeObject(value.task) + value.type != null -> generator.writeObject(value.type) value.scorer != null -> generator.writeObject(value.scorer) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Position") } } } - } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + @NoAutoDetect + class Type + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 type(): InnerType = type.getRequired("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + type() + validated = true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Type]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() } - return other is Type && this.value == other.value + /** A builder for [Type]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(type: Type) = apply { + this.type = type.type + additionalProperties = type.additionalProperties.toMutableMap() + } + + fun type(type: InnerType) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [InnerType] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [Type]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Type = + Type(checkRequired("type", type), additionalProperties.toImmutable()) + } + + class InnerType + @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 = of("task") + + @JvmStatic fun of(value: String) = InnerType(JsonField.of(value)) + } + + /** An enum containing [InnerType]'s known values. */ + enum class Known { + TASK + } + + /** + * An enum containing [InnerType]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [InnerType] 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, + /** + * An enum member indicating that [InnerType] 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 -> Value.TASK + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + TASK -> Known.TASK + else -> + throw BraintrustInvalidDataException( + "Unknown InnerType: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InnerType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Type{type=$type, additionalProperties=$additionalProperties}" } - override fun hashCode() = value.hashCode() + @NoAutoDetect + class Scorer + @JsonCreator + private constructor( + @JsonProperty("index") + @ExcludeMissing + private val index: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 index(): Long = index.getRequired("index") + + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [index]. + * + * Unlike [index], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("index") @ExcludeMissing fun _index(): JsonField = index + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Scorer = apply { + if (validated) { + return@apply + } - override fun toString() = value.toString() + index() + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Scorer]. + * + * The following fields are required: + * ```java + * .index() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scorer]. */ + class Builder internal constructor() { + + private var index: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(scorer: Scorer) = apply { + index = scorer.index + type = scorer.type + additionalProperties = scorer.additionalProperties.toMutableMap() + } + + fun index(index: Long) = index(JsonField.of(index)) + + /** + * Sets [Builder.index] to an arbitrary JSON value. + * + * You should usually call [Builder.index] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun index(index: JsonField) = apply { this.index = index } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [Scorer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .index() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Scorer = + Scorer( + checkRequired("index", index), + checkRequired("type", type), + additionalProperties.toImmutable(), + ) + } + + class Type + @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 SCORER = of("scorer") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + SCORER + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { + SCORER, + /** + * An enum member indicating that [Type] 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) { + SCORER -> Value.SCORER + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + SCORER -> Known.SCORER + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Scorer && index == other.index && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(index, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Scorer{index=$index, type=$type, additionalProperties=$additionalProperties}" + } + } + + class Type @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 EXPERIMENT = Type(JsonField.of("experiment")) + @JvmField val EXPERIMENT = of("experiment") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - EXPERIMENT, + EXPERIMENT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { EXPERIMENT, + /** + * An enum member indicating that [Type] 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) { EXPERIMENT -> Value.EXPERIMENT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { EXPERIMENT -> Known.EXPERIMENT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Experiment && evalName == other.evalName && position == other.position && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(evalName, position, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Experiment{evalName=$evalName, position=$position, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val type: JsonField, - private val index: JsonField, - private val additionalProperties: Map, + @JsonProperty("index") + @ExcludeMissing + private val index: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 index(): Long = index.getRequired("index") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun index(): Long = index.getRequired("index") + /** + * Returns the raw JSON value of [index]. + * + * Unlike [index], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("index") @ExcludeMissing fun _index(): JsonField = index - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("index") @ExcludeMissing fun _index() = index + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - type() - index() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.type == other.type && - this.index == other.index && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - index, - additionalProperties, - ) - } - return hashCode + index() + type() + validated = true } - override fun toString() = - "Function{type=$type, index=$index, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .index() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var index: JsonField = JsonMissing.of() + private var index: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.type = function.type - this.index = function.index - additionalProperties(function.additionalProperties) + index = function.index + type = function.type + additionalProperties = function.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun index(index: Long) = index(JsonField.of(index)) - @JsonProperty("index") - @ExcludeMissing + /** + * Sets [Builder.index] to an arbitrary JSON value. + * + * You should usually call [Builder.index] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun index(index: JsonField) = apply { this.index = index } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -707,220 +1480,352 @@ private constructor( 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .index() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( - type, - index, - additionalProperties.toUnmodifiable(), + checkRequired("index", index), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val FUNCTION = Type(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { FUNCTION, + /** + * An enum member indicating that [Type] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && index == other.index && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(index, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{index=$index, type=$type, additionalProperties=$additionalProperties}" } } - @JsonDeserialize(builder = RuntimeContext.Builder::class) @NoAutoDetect class RuntimeContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("runtime") @ExcludeMissing fun _runtime(): JsonField = runtime - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RuntimeContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RuntimeContext = apply { + if (validated) { + return@apply } - return other is RuntimeContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RuntimeContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RuntimeContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(runtimeContext: RuntimeContext) = apply { - this.runtime = runtimeContext.runtime - this.version = runtimeContext.version - additionalProperties(runtimeContext.additionalProperties) + runtime = runtimeContext.runtime + version = runtimeContext.version + additionalProperties = runtimeContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RuntimeContext]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RuntimeContext = RuntimeContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } - class Runtime - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Runtime @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -928,6 +1833,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -935,7 +1849,65 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown Runtime: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RuntimeContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is CodeBundle && bundleId == other.bundleId && location == other.location && runtimeContext == other.runtimeContext && preview == other.preview && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(bundleId, location, runtimeContext, preview, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CodeBundle{bundleId=$bundleId, location=$location, runtimeContext=$runtimeContext, preview=$preview, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CreateApiKeyOutput.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CreateApiKeyOutput.kt index f8043a78..24beff8e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CreateApiKeyOutput.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CreateApiKeyOutput.kt @@ -7,232 +7,355 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = CreateApiKeyOutput.Builder::class) @NoAutoDetect class CreateApiKeyOutput +@JsonCreator private constructor( - private val id: JsonField, - private val created: JsonField, - private val name: JsonField, - private val previewName: JsonField, - private val userId: JsonField, - private val orgId: JsonField, - private val key: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("key") @ExcludeMissing private val key: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("preview_name") + @ExcludeMissing + private val previewName: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the api key */ + /** + * Unique identifier for the api key + * + * @throws BraintrustInvalidDataException 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") - /** Date of api key creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + /** + * The raw API key. It will only be exposed this one time + * + * @throws BraintrustInvalidDataException 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 key(): String = key.getRequired("key") - /** Name of the api key */ + /** + * Name of the api key + * + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 previewName(): String = previewName.getRequired("preview_name") - /** Unique identifier for the user */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + /** + * Date of api key creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Unique identifier for the organization */ + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun orgId(): Optional = Optional.ofNullable(orgId.getNullable("org_id")) - /** The raw API key. It will only be exposed this one time */ - fun key(): String = key.getRequired("key") - - /** Unique identifier for the api key */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Date of api key creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Name of the api key */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonProperty("preview_name") @ExcludeMissing fun _previewName() = previewName - - /** Unique identifier for the user */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId - - /** Unique identifier for the organization */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + /** + * Unique identifier for the user + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** The raw API key. It will only be exposed this one time */ - @JsonProperty("key") @ExcludeMissing fun _key() = key + /** + * 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 [key]. + * + * Unlike [key], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("key") @ExcludeMissing fun _key(): JsonField = key + + /** + * 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 [previewName]. + * + * Unlike [previewName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("preview_name") + @ExcludeMissing + fun _previewName(): JsonField = previewName + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): CreateApiKeyOutput = apply { - if (!validated) { - id() - created() - name() - previewName() - userId() - orgId() - key() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): CreateApiKeyOutput = apply { + if (validated) { + return@apply } - return other is CreateApiKeyOutput && - this.id == other.id && - this.created == other.created && - this.name == other.name && - this.previewName == other.previewName && - this.userId == other.userId && - this.orgId == other.orgId && - this.key == other.key && - this.additionalProperties == other.additionalProperties + id() + key() + name() + previewName() + created() + orgId() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - created, - name, - previewName, - userId, - orgId, - key, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "CreateApiKeyOutput{id=$id, created=$created, name=$name, previewName=$previewName, userId=$userId, orgId=$orgId, key=$key, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [CreateApiKeyOutput]. + * + * The following fields are required: + * ```java + * .id() + * .key() + * .name() + * .previewName() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [CreateApiKeyOutput]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var key: JsonField? = null + private var name: JsonField? = null + private var previewName: JsonField? = null private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var previewName: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() private var orgId: JsonField = JsonMissing.of() - private var key: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(createApiKeyOutput: CreateApiKeyOutput) = apply { - this.id = createApiKeyOutput.id - this.created = createApiKeyOutput.created - this.name = createApiKeyOutput.name - this.previewName = createApiKeyOutput.previewName - this.userId = createApiKeyOutput.userId - this.orgId = createApiKeyOutput.orgId - this.key = createApiKeyOutput.key - additionalProperties(createApiKeyOutput.additionalProperties) + id = createApiKeyOutput.id + key = createApiKeyOutput.key + name = createApiKeyOutput.name + previewName = createApiKeyOutput.previewName + created = createApiKeyOutput.created + orgId = createApiKeyOutput.orgId + userId = createApiKeyOutput.userId + additionalProperties = createApiKeyOutput.additionalProperties.toMutableMap() } /** Unique identifier for the api key */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the api key */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } - /** Date of api key creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** The raw API key. It will only be exposed this one time */ + fun key(key: String) = key(JsonField.of(key)) - /** Date of api key creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * Sets [Builder.key] to an arbitrary JSON value. + * + * You should usually call [Builder.key] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun key(key: JsonField) = apply { this.key = key } /** Name of the api key */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the api key */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun previewName(previewName: String) = previewName(JsonField.of(previewName)) - @JsonProperty("preview_name") - @ExcludeMissing + /** + * Sets [Builder.previewName] to an arbitrary JSON value. + * + * You should usually call [Builder.previewName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun previewName(previewName: JsonField) = apply { this.previewName = previewName } - /** Unique identifier for the user */ - fun userId(userId: String) = userId(JsonField.of(userId)) - - /** Unique identifier for the user */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + /** Date of api key creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } /** Unique identifier for the organization */ - fun orgId(orgId: String) = orgId(JsonField.of(orgId)) + fun orgId(orgId: String?) = orgId(JsonField.ofNullable(orgId)) - /** Unique identifier for the organization */ - @JsonProperty("org_id") - @ExcludeMissing + /** Alias for calling [Builder.orgId] with `orgId.orElse(null)`. */ + fun orgId(orgId: Optional) = orgId(orgId.getOrNull()) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - /** The raw API key. It will only be exposed this one time */ - fun key(key: String) = key(JsonField.of(key)) + /** Unique identifier for the user */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - /** The raw API key. It will only be exposed this one time */ - @JsonProperty("key") - @ExcludeMissing - fun key(key: JsonField) = apply { this.key = key } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [CreateApiKeyOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .key() + * .name() + * .previewName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): CreateApiKeyOutput = CreateApiKeyOutput( - id, + checkRequired("id", id), + checkRequired("key", key), + checkRequired("name", name), + checkRequired("previewName", previewName), created, - name, - previewName, - userId, orgId, - key, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is CreateApiKeyOutput && id == other.id && key == other.key && name == other.name && previewName == other.previewName && created == other.created && orgId == other.orgId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, key, name, previewName, created, orgId, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CreateApiKeyOutput{id=$id, key=$key, name=$name, previewName=$previewName, created=$created, orgId=$orgId, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponse.kt index 9c3ace5c..2b7bead1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponse.kt @@ -7,376 +7,475 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = CrossObjectInsertResponse.Builder::class) @NoAutoDetect class CrossObjectInsertResponse +@JsonCreator private constructor( - private val experiment: JsonField, - private val dataset: JsonField, - private val projectLogs: JsonField, - private val additionalProperties: Map, + @JsonProperty("dataset") + @ExcludeMissing + private val dataset: JsonField = JsonMissing.of(), + @JsonProperty("experiment") + @ExcludeMissing + private val experiment: JsonField = JsonMissing.of(), + @JsonProperty("project_logs") + @ExcludeMissing + private val projectLogs: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * A mapping from dataset id to row ids for inserted `events` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun dataset(): Optional = Optional.ofNullable(dataset.getNullable("dataset")) - /** A mapping from experiment id to row ids for inserted `events` */ + /** + * A mapping from experiment id to row ids for inserted `events` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun experiment(): Optional = Optional.ofNullable(experiment.getNullable("experiment")) - /** A mapping from dataset id to row ids for inserted `events` */ - fun dataset(): Optional = Optional.ofNullable(dataset.getNullable("dataset")) - - /** A mapping from project id to row ids for inserted `events` */ + /** + * A mapping from project id to row ids for inserted `events` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun projectLogs(): Optional = Optional.ofNullable(projectLogs.getNullable("project_logs")) - /** A mapping from experiment id to row ids for inserted `events` */ - @JsonProperty("experiment") @ExcludeMissing fun _experiment() = experiment - - /** A mapping from dataset id to row ids for inserted `events` */ - @JsonProperty("dataset") @ExcludeMissing fun _dataset() = dataset - - /** A mapping from project id to row ids for inserted `events` */ - @JsonProperty("project_logs") @ExcludeMissing fun _projectLogs() = projectLogs + /** + * Returns the raw JSON value of [dataset]. + * + * Unlike [dataset], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset") @ExcludeMissing fun _dataset(): JsonField = dataset + + /** + * Returns the raw JSON value of [experiment]. + * + * Unlike [experiment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("experiment") + @ExcludeMissing + fun _experiment(): JsonField = experiment + + /** + * Returns the raw JSON value of [projectLogs]. + * + * Unlike [projectLogs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_logs") + @ExcludeMissing + fun _projectLogs(): JsonField = projectLogs @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): CrossObjectInsertResponse = apply { - if (!validated) { - experiment().map { it.validate() } - dataset().map { it.validate() } - projectLogs().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): CrossObjectInsertResponse = apply { + if (validated) { + return@apply } - return other is CrossObjectInsertResponse && - this.experiment == other.experiment && - this.dataset == other.dataset && - this.projectLogs == other.projectLogs && - this.additionalProperties == other.additionalProperties + dataset().ifPresent { it.validate() } + experiment().ifPresent { it.validate() } + projectLogs().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - experiment, - dataset, - projectLogs, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "CrossObjectInsertResponse{experiment=$experiment, dataset=$dataset, projectLogs=$projectLogs, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [CrossObjectInsertResponse]. + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [CrossObjectInsertResponse]. */ + class Builder internal constructor() { - private var experiment: JsonField = JsonMissing.of() private var dataset: JsonField = JsonMissing.of() + private var experiment: JsonField = JsonMissing.of() private var projectLogs: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(crossObjectInsertResponse: CrossObjectInsertResponse) = apply { - this.experiment = crossObjectInsertResponse.experiment - this.dataset = crossObjectInsertResponse.dataset - this.projectLogs = crossObjectInsertResponse.projectLogs - additionalProperties(crossObjectInsertResponse.additionalProperties) + dataset = crossObjectInsertResponse.dataset + experiment = crossObjectInsertResponse.experiment + projectLogs = crossObjectInsertResponse.projectLogs + additionalProperties = crossObjectInsertResponse.additionalProperties.toMutableMap() } - /** A mapping from experiment id to row ids for inserted `events` */ - fun experiment(experiment: Experiment) = experiment(JsonField.of(experiment)) - - /** A mapping from experiment id to row ids for inserted `events` */ - @JsonProperty("experiment") - @ExcludeMissing - fun experiment(experiment: JsonField) = apply { this.experiment = experiment } - /** A mapping from dataset id to row ids for inserted `events` */ - fun dataset(dataset: Dataset) = dataset(JsonField.of(dataset)) + fun dataset(dataset: Dataset?) = dataset(JsonField.ofNullable(dataset)) - /** A mapping from dataset id to row ids for inserted `events` */ - @JsonProperty("dataset") - @ExcludeMissing + /** Alias for calling [Builder.dataset] with `dataset.orElse(null)`. */ + fun dataset(dataset: Optional) = dataset(dataset.getOrNull()) + + /** + * Sets [Builder.dataset] to an arbitrary JSON value. + * + * You should usually call [Builder.dataset] with a well-typed [Dataset] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun dataset(dataset: JsonField) = apply { this.dataset = dataset } - /** A mapping from project id to row ids for inserted `events` */ - fun projectLogs(projectLogs: ProjectLogs) = projectLogs(JsonField.of(projectLogs)) + /** A mapping from experiment id to row ids for inserted `events` */ + fun experiment(experiment: Experiment?) = experiment(JsonField.ofNullable(experiment)) + + /** Alias for calling [Builder.experiment] with `experiment.orElse(null)`. */ + fun experiment(experiment: Optional) = experiment(experiment.getOrNull()) + + /** + * Sets [Builder.experiment] to an arbitrary JSON value. + * + * You should usually call [Builder.experiment] with a well-typed [Experiment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun experiment(experiment: JsonField) = apply { this.experiment = experiment } /** A mapping from project id to row ids for inserted `events` */ - @JsonProperty("project_logs") - @ExcludeMissing + fun projectLogs(projectLogs: ProjectLogs?) = projectLogs(JsonField.ofNullable(projectLogs)) + + /** Alias for calling [Builder.projectLogs] with `projectLogs.orElse(null)`. */ + fun projectLogs(projectLogs: Optional) = projectLogs(projectLogs.getOrNull()) + + /** + * Sets [Builder.projectLogs] to an arbitrary JSON value. + * + * You should usually call [Builder.projectLogs] with a well-typed [ProjectLogs] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun projectLogs(projectLogs: JsonField) = apply { this.projectLogs = projectLogs } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [CrossObjectInsertResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): CrossObjectInsertResponse = CrossObjectInsertResponse( - experiment, dataset, + experiment, projectLogs, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } /** A mapping from dataset id to row ids for inserted `events` */ - @JsonDeserialize(builder = Dataset.Builder::class) @NoAutoDetect class Dataset + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Dataset = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Dataset = apply { + if (validated) { + return@apply } - return other is Dataset && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Dataset{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Dataset]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Dataset]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(dataset: Dataset) = apply { - additionalProperties(dataset.additionalProperties) + additionalProperties = dataset.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Dataset = Dataset(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Dataset]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Dataset = Dataset(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Dataset && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Dataset{additionalProperties=$additionalProperties}" } /** A mapping from experiment id to row ids for inserted `events` */ - @JsonDeserialize(builder = Experiment.Builder::class) @NoAutoDetect class Experiment + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Experiment = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Experiment = apply { + if (validated) { + return@apply } - return other is Experiment && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Experiment{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Experiment]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Experiment]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(experiment: Experiment) = apply { - additionalProperties(experiment.additionalProperties) + additionalProperties = experiment.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Experiment = Experiment(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Experiment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Experiment = Experiment(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Experiment && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Experiment{additionalProperties=$additionalProperties}" } /** A mapping from project id to row ids for inserted `events` */ - @JsonDeserialize(builder = ProjectLogs.Builder::class) @NoAutoDetect class ProjectLogs + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectLogs = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectLogs = apply { + if (validated) { + return@apply } - return other is ProjectLogs && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "ProjectLogs{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ProjectLogs]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectLogs]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectLogs: ProjectLogs) = apply { - additionalProperties(projectLogs.additionalProperties) + additionalProperties = projectLogs.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectLogs = ProjectLogs(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ProjectLogs]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ProjectLogs = ProjectLogs(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectLogs && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "ProjectLogs{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is CrossObjectInsertResponse && dataset == other.dataset && experiment == other.experiment && projectLogs == other.projectLogs && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(dataset, experiment, projectLogs, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CrossObjectInsertResponse{dataset=$dataset, experiment=$experiment, projectLogs=$projectLogs, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DataSummary.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DataSummary.kt index 09ea8607..cdcf9fe8 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DataSummary.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DataSummary.kt @@ -7,103 +7,150 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects /** Summary of a dataset's data */ -@JsonDeserialize(builder = DataSummary.Builder::class) @NoAutoDetect class DataSummary +@JsonCreator private constructor( - private val totalRecords: JsonField, - private val additionalProperties: Map, + @JsonProperty("total_records") + @ExcludeMissing + private val totalRecords: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Total number of records in the dataset */ + /** + * Total number of records in the dataset + * + * @throws BraintrustInvalidDataException 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 totalRecords(): Long = totalRecords.getRequired("total_records") - /** Total number of records in the dataset */ - @JsonProperty("total_records") @ExcludeMissing fun _totalRecords() = totalRecords + /** + * Returns the raw JSON value of [totalRecords]. + * + * Unlike [totalRecords], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("total_records") + @ExcludeMissing + fun _totalRecords(): JsonField = totalRecords @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): DataSummary = apply { - if (!validated) { - totalRecords() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): DataSummary = apply { + if (validated) { + return@apply } - return other is DataSummary && - this.totalRecords == other.totalRecords && - this.additionalProperties == other.additionalProperties + totalRecords() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(totalRecords, additionalProperties) - } - return hashCode - } - - override fun toString() = - "DataSummary{totalRecords=$totalRecords, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DataSummary]. + * + * The following fields are required: + * ```java + * .totalRecords() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [DataSummary]. */ + class Builder internal constructor() { - private var totalRecords: JsonField = JsonMissing.of() + private var totalRecords: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(dataSummary: DataSummary) = apply { - this.totalRecords = dataSummary.totalRecords - additionalProperties(dataSummary.additionalProperties) + totalRecords = dataSummary.totalRecords + additionalProperties = dataSummary.additionalProperties.toMutableMap() } /** Total number of records in the dataset */ fun totalRecords(totalRecords: Long) = totalRecords(JsonField.of(totalRecords)) - /** Total number of records in the dataset */ - @JsonProperty("total_records") - @ExcludeMissing + /** + * Sets [Builder.totalRecords] to an arbitrary JSON value. + * + * You should usually call [Builder.totalRecords] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun totalRecords(totalRecords: JsonField) = apply { this.totalRecords = totalRecords } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DataSummary = DataSummary(totalRecords, additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [DataSummary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .totalRecords() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): DataSummary = + DataSummary( + checkRequired("totalRecords", totalRecords), + additionalProperties.toImmutable(), + ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DataSummary && totalRecords == other.totalRecords && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(totalRecords, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DataSummary{totalRecords=$totalRecords, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Dataset.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Dataset.kt index 6ff84bcd..e0a65784 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Dataset.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Dataset.kt @@ -7,332 +7,489 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Dataset.Builder::class) @NoAutoDetect class Dataset +@JsonCreator private constructor( - private val id: JsonField, - private val projectId: JsonField, - private val name: JsonField, - private val description: JsonField, - private val created: JsonField, - private val deletedAt: JsonField, - private val userId: JsonField, - private val metadata: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the dataset */ + /** + * Unique identifier for the dataset + * + * @throws BraintrustInvalidDataException 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") - /** Unique identifier for the project that the dataset belongs under */ - fun projectId(): String = projectId.getRequired("project_id") - - /** Name of the dataset. Within a project, dataset names are unique */ + /** + * Name of the dataset. Within a project, dataset names are unique + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the dataset */ - fun description(): Optional = - Optional.ofNullable(description.getNullable("description")) + /** + * Unique identifier for the project that the dataset belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Date of dataset creation */ + /** + * Date of dataset creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Date of dataset deletion, or null if the dataset is still active */ + /** + * Date of dataset deletion, or null if the dataset is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun deletedAt(): Optional = Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Identifies the user who created the dataset */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + /** + * Textual description of the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** User-controlled metadata about the dataset */ + /** + * User-controlled metadata about the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** Unique identifier for the dataset */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId - - /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Textual description of the dataset */ - @JsonProperty("description") @ExcludeMissing fun _description() = description - - /** Date of dataset creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Date of dataset deletion, or null if the dataset is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt - - /** Identifies the user who created the dataset */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * Identifies the user who created the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** User-controlled metadata about the dataset */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + /** + * 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 [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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Dataset = apply { - if (!validated) { - id() - projectId() - name() - description() - created() - deletedAt() - userId() - metadata().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Dataset = apply { + if (validated) { + return@apply } - return other is Dataset && - this.id == other.id && - this.projectId == other.projectId && - this.name == other.name && - this.description == other.description && - this.created == other.created && - this.deletedAt == other.deletedAt && - this.userId == other.userId && - this.metadata == other.metadata && - this.additionalProperties == other.additionalProperties + id() + name() + projectId() + created() + deletedAt() + description() + metadata().ifPresent { it.validate() } + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - projectId, - name, - description, - created, - deletedAt, - userId, - metadata, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Dataset{id=$id, projectId=$projectId, name=$name, description=$description, created=$created, deletedAt=$deletedAt, userId=$userId, metadata=$metadata, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Dataset]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Dataset]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null private var created: JsonField = JsonMissing.of() private var deletedAt: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(dataset: Dataset) = apply { - this.id = dataset.id - this.projectId = dataset.projectId - this.name = dataset.name - this.description = dataset.description - this.created = dataset.created - this.deletedAt = dataset.deletedAt - this.userId = dataset.userId - this.metadata = dataset.metadata - additionalProperties(dataset.additionalProperties) + id = dataset.id + name = dataset.name + projectId = dataset.projectId + created = dataset.created + deletedAt = dataset.deletedAt + description = dataset.description + metadata = dataset.metadata + userId = dataset.userId + additionalProperties = dataset.additionalProperties.toMutableMap() } /** Unique identifier for the dataset */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the dataset */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Unique identifier for the project that the dataset belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - - /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + /** + * 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 } /** Name of the dataset. Within a project, dataset names are unique */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } - /** Textual description of the dataset */ - fun description(description: String) = description(JsonField.of(description)) - - /** Textual description of the dataset */ - @JsonProperty("description") - @ExcludeMissing - fun description(description: JsonField) = apply { this.description = description } + /** Unique identifier for the project that the dataset belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Date of dataset creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Date of dataset creation */ - @JsonProperty("created") - @ExcludeMissing + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } /** Date of dataset deletion, or null if the dataset is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) - - /** Date of dataset deletion, or null if the dataset is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } - /** Identifies the user who created the dataset */ - fun userId(userId: String) = userId(JsonField.of(userId)) + /** Textual description of the dataset */ + 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 } + + /** User-controlled metadata about the dataset */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** Identifies the user who created the dataset */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - /** User-controlled metadata about the dataset */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - /** User-controlled metadata about the dataset */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Dataset]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Dataset = Dataset( - id, - projectId, - name, - description, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("projectId", projectId), created, deletedAt, - userId, + description, metadata, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } /** User-controlled metadata about the dataset */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Dataset && id == other.id && name == other.name && projectId == other.projectId && created == other.created && deletedAt == other.deletedAt && description == other.description && metadata == other.metadata && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, projectId, created, deletedAt, description, metadata, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Dataset{id=$id, name=$name, projectId=$projectId, created=$created, deletedAt=$deletedAt, description=$description, metadata=$metadata, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetCreateParams.kt index 4146c66e..fb4cd2c4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetCreateParams.kt @@ -3,289 +3,676 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new dataset. If there is an existing dataset in the project with the same name as the + * one specified in the request, will return the existing dataset unmodified + */ class DatasetCreateParams -constructor( - private val name: String, - private val projectId: String, - private val description: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun description(): Optional = Optional.ofNullable(description) - - @JvmSynthetic - internal fun getBody(): DatasetCreateBody { - return DatasetCreateBody( - name, - projectId, - description, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the dataset. Within a project, dataset names are unique + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the dataset belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Textual description of the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * User-controlled metadata about the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = DatasetCreateBody.Builder::class) @NoAutoDetect - class DatasetCreateBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val description: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId + /** + * Name of the dataset. Within a project, dataset names are unique + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the dataset belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * Textual description of the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * User-controlled metadata about the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * 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 - /** Textual description of the dataset */ - @JsonProperty("description") fun description(): String? = description + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is DatasetCreateBody && - this.name == other.name && - this.projectId == other.projectId && - this.description == other.description && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - description, - additionalProperties, - ) - } - return hashCode + name() + projectId() + description() + metadata().ifPresent { it.validate() } + validated = true } - override fun toString() = - "DatasetCreateBody{name=$name, projectId=$projectId, description=$description, additionalProperties=$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() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var description: String? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(datasetCreateBody: DatasetCreateBody) = apply { - this.name = datasetCreateBody.name - this.projectId = datasetCreateBody.projectId - this.description = datasetCreateBody.description - additionalProperties(datasetCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + description = body.description + metadata = body.metadata + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Textual description of the dataset */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } + + /** User-controlled metadata about the dataset */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DatasetCreateBody = - DatasetCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, + 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() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), description, - additionalProperties.toUnmodifiable(), + metadata, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && description == other.description && metadata == other.metadata && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is DatasetCreateParams && - this.name == other.name && - this.projectId == other.projectId && - this.description == other.description && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, description, metadata, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - description, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "DatasetCreateParams{name=$name, projectId=$projectId, description=$description, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, description=$description, metadata=$metadata, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var description: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(datasetCreateParams: DatasetCreateParams) = apply { - this.name = datasetCreateParams.name - this.projectId = datasetCreateParams.projectId - this.description = datasetCreateParams.description - additionalQueryParams(datasetCreateParams.additionalQueryParams) - additionalHeaders(datasetCreateParams.additionalHeaders) - additionalBodyProperties(datasetCreateParams.additionalBodyProperties) + body = datasetCreateParams.body.toBuilder() + additionalHeaders = datasetCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetCreateParams.additionalQueryParams.toBuilder() } /** Name of the dataset. Within a project, dataset names are unique */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the dataset belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Textual description of the dataset */ - fun description(description: String) = apply { this.description = description } + 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) } + + /** User-controlled metadata about the dataset */ + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [DatasetCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetCreateParams = DatasetCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - description, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + /** User-controlled metadata about the dataset */ + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetDeleteParams.kt index 29ce38b2..67c7b316 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a dataset object by its id */ class DatasetDeleteParams -constructor( +private constructor( private val datasetId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DatasetDeleteParams && - this.datasetId == other.datasetId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - datasetId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "DatasetDeleteParams{datasetId=$datasetId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetDeleteParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(datasetDeleteParams: DatasetDeleteParams) = apply { - this.datasetId = datasetDeleteParams.datasetId - additionalQueryParams(datasetDeleteParams.additionalQueryParams) - additionalHeaders(datasetDeleteParams.additionalHeaders) - additionalBodyProperties(datasetDeleteParams.additionalBodyProperties) + datasetId = datasetDeleteParams.datasetId + additionalHeaders = datasetDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = datasetDeleteParams.additionalBodyProperties.toMutableMap() } /** Dataset id */ fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [DatasetDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetDeleteParams = DatasetDeleteParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("datasetId", datasetId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetDeleteParams && datasetId == other.datasetId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "DatasetDeleteParams{datasetId=$datasetId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetEvent.kt index 1ea168ef..28bf576a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetEvent.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetEvent.kt @@ -7,40 +7,66 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = DatasetEvent.Builder::class) @NoAutoDetect class DatasetEvent +@JsonCreator private constructor( - private val id: JsonField, - private val _xactId: JsonField, - private val created: JsonField, - private val projectId: JsonField, - private val datasetId: JsonField, - private val input: JsonValue, - private val expected: JsonValue, - private val metadata: JsonField, - private val tags: JsonField>, - private val spanId: JsonField, - private val rootSpanId: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("dataset_id") + @ExcludeMissing + private val datasetId: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("is_root") + @ExcludeMissing + private val isRoot: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate * one for you + * + * @throws BraintrustInvalidDataException 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") @@ -48,26 +74,70 @@ private constructor( * The transaction id of an event is unique to the network operation that processed the event * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve * a versioned snapshot of the dataset (see the `version` parameter) + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") - /** The timestamp the dataset event was created */ + /** + * The timestamp the dataset event was created + * + * @throws BraintrustInvalidDataException 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 created(): OffsetDateTime = created.getRequired("created") - /** Unique identifier for the project that the dataset belongs under */ + /** + * Unique identifier for the dataset + * + * @throws BraintrustInvalidDataException 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 datasetId(): String = datasetId.getRequired("dataset_id") + + /** + * Unique identifier for the project that the dataset belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the dataset */ - fun datasetId(): String = datasetId.getRequired("dataset_id") + /** + * A unique identifier for the trace this dataset event belongs to + * + * @throws BraintrustInvalidDataException 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 rootSpanId(): String = rootSpanId.getRequired("root_span_id") - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - fun input(): JsonValue = input + /** + * A unique identifier used to link different dataset events together as part of a full trace. + * See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full details on + * tracing + * + * @throws BraintrustInvalidDataException 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 spanId(): String = spanId.getRequired("span_id") /** * The output of your application, including post-processing (an arbitrary, JSON serializable * object) */ - fun expected(): JsonValue = expected + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected + + /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input + + /** + * Whether this span is a root span + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun isRoot(): Optional = Optional.ofNullable(isRoot.getNullable("is_root")) /** * A dictionary with additional data about the test example, model outputs, or just about @@ -75,176 +145,185 @@ private constructor( * example, you could log the `prompt`, example's `id`, or anything else that would be useful to * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** - * A unique identifier used to link different dataset events together as part of a full trace. - * See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full details on - * tracing + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun spanId(): String = spanId.getRequired("span_id") + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) - /** The `span_id` of the root of the trace this dataset event belongs to */ - fun rootSpanId(): String = rootSpanId.getRequired("root_span_id") + /** + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate - * one for you + * 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() = id + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id /** - * The transaction id of an event is unique to the network operation that processed the event - * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve - * a versioned snapshot of the dataset (see the `version` parameter) + * Returns the raw JSON value of [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("_xact_id") @ExcludeMissing fun __xactId() = _xactId + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId - /** The timestamp the dataset event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId(): JsonField = datasetId - /** Unique identifier for the dataset */ - @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId() = datasetId + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - @JsonProperty("input") @ExcludeMissing fun _input() = input + /** + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object) + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings + * Returns the raw JSON value of [isRoot]. + * + * Unlike [isRoot], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("is_root") @ExcludeMissing fun _isRoot(): JsonField = isRoot - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * A unique identifier used to link different dataset events together as part of a full trace. - * See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full details on - * tracing + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("span_id") @ExcludeMissing fun _spanId() = spanId + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin - /** The `span_id` of the root of the trace this dataset event belongs to */ - @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId() = rootSpanId + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): DatasetEvent = apply { - if (!validated) { - id() - _xactId() - created() - projectId() - datasetId() - input() - expected() - metadata().map { it.validate() } - tags() - spanId() - rootSpanId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): DatasetEvent = apply { + if (validated) { + return@apply } - return other is DatasetEvent && - this.id == other.id && - this._xactId == other._xactId && - this.created == other.created && - this.projectId == other.projectId && - this.datasetId == other.datasetId && - this.input == other.input && - this.expected == other.expected && - this.metadata == other.metadata && - this.tags == other.tags && - this.spanId == other.spanId && - this.rootSpanId == other.rootSpanId && - this.additionalProperties == other.additionalProperties + id() + _xactId() + created() + datasetId() + projectId() + rootSpanId() + spanId() + isRoot() + metadata().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - _xactId, - created, - projectId, - datasetId, - input, - expected, - metadata, - tags, - spanId, - rootSpanId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "DatasetEvent{id=$id, _xactId=$_xactId, created=$created, projectId=$projectId, datasetId=$datasetId, input=$input, expected=$expected, metadata=$metadata, tags=$tags, spanId=$spanId, rootSpanId=$rootSpanId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetEvent]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .datasetId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [DatasetEvent]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var _xactId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var datasetId: JsonField = JsonMissing.of() - private var input: JsonValue = JsonMissing.of() + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var created: JsonField? = null + private var datasetId: JsonField? = null + private var projectId: JsonField? = null + private var rootSpanId: JsonField? = null + private var spanId: JsonField? = null private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var isRoot: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var spanId: JsonField = JsonMissing.of() - private var rootSpanId: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(datasetEvent: DatasetEvent) = apply { - this.id = datasetEvent.id - this._xactId = datasetEvent._xactId - this.created = datasetEvent.created - this.projectId = datasetEvent.projectId - this.datasetId = datasetEvent.datasetId - this.input = datasetEvent.input - this.expected = datasetEvent.expected - this.metadata = datasetEvent.metadata - this.tags = datasetEvent.tags - this.spanId = datasetEvent.spanId - this.rootSpanId = datasetEvent.rootSpanId - additionalProperties(datasetEvent.additionalProperties) + id = datasetEvent.id + _xactId = datasetEvent._xactId + created = datasetEvent.created + datasetId = datasetEvent.datasetId + projectId = datasetEvent.projectId + rootSpanId = datasetEvent.rootSpanId + spanId = datasetEvent.spanId + expected = datasetEvent.expected + input = datasetEvent.input + isRoot = datasetEvent.isRoot + metadata = datasetEvent.metadata + origin = datasetEvent.origin + tags = datasetEvent.tags.map { it.toMutableList() } + additionalProperties = datasetEvent.additionalProperties.toMutableMap() } /** @@ -254,10 +333,12 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will - * generate one for you + * 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. */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } + fun id(id: JsonField) = apply { this.id = id } /** * The transaction id of an event is unique to the network operation that processed the @@ -267,61 +348,107 @@ private constructor( fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) /** - * The transaction id of an event is unique to the network operation that processed the - * event insertion. Transaction ids are monotonically increasing over time and can be used - * to retrieve a versioned snapshot of the dataset (see the `version` parameter) + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("_xact_id") - @ExcludeMissing fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } /** The timestamp the dataset event was created */ fun created(created: OffsetDateTime) = created(JsonField.of(created)) - /** The timestamp the dataset event was created */ - @JsonProperty("created") - @ExcludeMissing + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } + /** Unique identifier for the dataset */ + fun datasetId(datasetId: String) = datasetId(JsonField.of(datasetId)) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } + /** Unique identifier for the project that the dataset belongs under */ fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Unique identifier for the project that the dataset belongs under */ - @JsonProperty("project_id") - @ExcludeMissing + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - /** Unique identifier for the dataset */ - fun datasetId(datasetId: String) = datasetId(JsonField.of(datasetId)) + /** A unique identifier for the trace this dataset event belongs to */ + fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) - /** Unique identifier for the dataset */ - @JsonProperty("dataset_id") - @ExcludeMissing - fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } /** - * The argument that uniquely define an input case (an arbitrary, JSON serializable object) + * A unique identifier used to link different dataset events together as part of a full + * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full + * details on tracing */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } + fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } /** * The output of your application, including post-processing (an arbitrary, JSON * serializable object) */ - @JsonProperty("expected") - @ExcludeMissing fun expected(expected: JsonValue) = apply { this.expected = expected } /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings + * The argument that uniquely define an input case (an arbitrary, JSON serializable object) + */ + fun input(input: JsonValue) = apply { this.input = input } + + /** Whether this span is a root span */ + fun isRoot(isRoot: Boolean?) = isRoot(JsonField.ofNullable(isRoot)) + + /** + * Alias for [Builder.isRoot]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isRoot(isRoot: Boolean) = isRoot(isRoot as Boolean?) + + /** Alias for calling [Builder.isRoot] with `isRoot.orElse(null)`. */ + fun isRoot(isRoot: Optional) = isRoot(isRoot.getOrNull()) + + /** + * Sets [Builder.isRoot] to an arbitrary JSON value. + * + * You should usually call [Builder.isRoot] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun isRoot(isRoot: JsonField) = apply { this.isRoot = isRoot } /** * A dictionary with additional data about the test example, model outputs, or just about @@ -330,70 +457,114 @@ private constructor( * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, * but its keys must be strings */ - @JsonProperty("metadata") - @ExcludeMissing + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) /** - * A unique identifier used to link different dataset events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + fun origin(origin: JsonField) = apply { this.origin = origin } + + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) /** - * A unique identifier used to link different dataset events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * 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. */ - @JsonProperty("span_id") - @ExcludeMissing - fun spanId(spanId: JsonField) = apply { this.spanId = spanId } - - /** The `span_id` of the root of the trace this dataset event belongs to */ - fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) + fun tags(tags: JsonField>) = apply { + this.tags = tags.map { it.toMutableList() } + } - /** The `span_id` of the root of the trace this dataset event belongs to */ - @JsonProperty("root_span_id") - @ExcludeMissing - fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [DatasetEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .datasetId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetEvent = DatasetEvent( - id, - _xactId, - created, - projectId, - datasetId, - input, + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("created", created), + checkRequired("datasetId", datasetId), + checkRequired("projectId", projectId), + checkRequired("rootSpanId", rootSpanId), + checkRequired("spanId", spanId), expected, + input, + isRoot, metadata, - tags.map { it.toUnmodifiable() }, - spanId, - rootSpanId, - additionalProperties.toUnmodifiable(), + origin, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } @@ -404,75 +575,141 @@ private constructor( * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) - private var hashCode: Int = 0 + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + model() + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { + private var model: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() } + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetEvent && id == other.id && _xactId == other._xactId && created == other.created && datasetId == other.datasetId && projectId == other.projectId && rootSpanId == other.rootSpanId && spanId == other.spanId && expected == other.expected && input == other.input && isRoot == other.isRoot && metadata == other.metadata && origin == other.origin && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, created, datasetId, projectId, rootSpanId, spanId, expected, input, isRoot, metadata, origin, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DatasetEvent{id=$id, _xactId=$_xactId, created=$created, datasetId=$datasetId, projectId=$projectId, rootSpanId=$rootSpanId, spanId=$spanId, expected=$expected, input=$input, isRoot=$isRoot, metadata=$metadata, origin=$origin, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFeedbackParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFeedbackParams.kt index c32d823b..bb641fb0 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFeedbackParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFeedbackParams.kt @@ -3,37 +3,62 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects +/** Log feedback for a set of dataset events */ class DatasetFeedbackParams -constructor( +private constructor( private val datasetId: String, - private val feedback: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId - fun feedback(): List = feedback + /** + * A list of dataset feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = body.feedback() - @JvmSynthetic - internal fun getBody(): DatasetFeedbackBody { - return DatasetFeedbackBody(feedback, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _feedback(): JsonField> = body._feedback() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -42,219 +67,364 @@ constructor( } } - @JsonDeserialize(builder = DatasetFeedbackBody.Builder::class) @NoAutoDetect - class DatasetFeedbackBody - internal constructor( - private val feedback: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("feedback") + @ExcludeMissing + private val feedback: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of dataset feedback items */ - @JsonProperty("feedback") fun feedback(): List? = feedback + /** + * A list of dataset feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = feedback.getRequired("feedback") + + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feedback") + @ExcludeMissing + fun _feedback(): JsonField> = feedback @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is DatasetFeedbackBody && - this.feedback == other.feedback && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(feedback, additionalProperties) - } - return hashCode + feedback().forEach { it.validate() } + validated = true } - override fun toString() = - "DatasetFeedbackBody{feedback=$feedback, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var feedback: List? = null + private var feedback: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(datasetFeedbackBody: DatasetFeedbackBody) = apply { - this.feedback = datasetFeedbackBody.feedback - additionalProperties(datasetFeedbackBody.additionalProperties) + internal fun from(body: Body) = apply { + feedback = body.feedback.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of dataset feedback items */ - @JsonProperty("feedback") - fun feedback(feedback: List) = apply { this.feedback = feedback } + fun feedback(feedback: List) = feedback(JsonField.of(feedback)) + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + this.feedback = feedback.map { it.toMutableList() } + } + + /** + * Adds a single [FeedbackDatasetItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackDatasetItem) = apply { + this.feedback = + (this.feedback ?: JsonField.of(mutableListOf())).also { + checkKnown("feedback", it).add(feedback) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DatasetFeedbackBody = - DatasetFeedbackBody( - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("feedback", feedback).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && feedback == other.feedback && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is DatasetFeedbackParams && - this.datasetId == other.datasetId && - this.feedback == other.feedback && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(feedback, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - datasetId, - feedback, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "DatasetFeedbackParams{datasetId=$datasetId, feedback=$feedback, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{feedback=$feedback, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetFeedbackParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetFeedbackParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var feedback: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(datasetFeedbackParams: DatasetFeedbackParams) = apply { - this.datasetId = datasetFeedbackParams.datasetId - this.feedback(datasetFeedbackParams.feedback) - additionalQueryParams(datasetFeedbackParams.additionalQueryParams) - additionalHeaders(datasetFeedbackParams.additionalHeaders) - additionalBodyProperties(datasetFeedbackParams.additionalBodyProperties) + datasetId = datasetFeedbackParams.datasetId + body = datasetFeedbackParams.body.toBuilder() + additionalHeaders = datasetFeedbackParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetFeedbackParams.additionalQueryParams.toBuilder() } /** Dataset id */ fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } /** A list of dataset feedback items */ - fun feedback(feedback: List) = apply { - this.feedback.clear() - this.feedback.addAll(feedback) + fun feedback(feedback: List) = apply { body.feedback(feedback) } + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + body.feedback(feedback) } - /** A list of dataset feedback items */ - fun addFeedback(feedback: FeedbackDatasetItem) = apply { this.feedback.add(feedback) } + /** + * Adds a single [FeedbackDatasetItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackDatasetItem) = apply { body.addFeedback(feedback) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [DatasetFeedbackParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetFeedbackParams = DatasetFeedbackParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("datasetId", datasetId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetFeedbackParams && datasetId == other.datasetId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetFeedbackParams{datasetId=$datasetId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchParams.kt index 1698818b..b00ce504 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchParams.kt @@ -3,44 +3,101 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in a dataset. Equivalent to the POST form of the same path, but with the + * parameters in the URL query rather than in the request body. For more complex queries, use the + * `POST /btql` endpoint. + */ class DatasetFetchParams -constructor( +private constructor( private val datasetId: String, private val limit: Long?, private val maxRootSpanId: String?, private val maxXactId: String?, private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + */ fun limit(): Optional = Optional.ofNullable(limit) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxXactId(): Optional = Optional.ofNullable(maxXactId) + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + */ fun version(): Optional = Optional.ofNullable(version) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.maxRootSpanId?.let { params.put("max_root_span_id", listOf(it.toString())) } - this.maxXactId?.let { params.put("max_xact_id", listOf(it.toString())) } - this.version?.let { params.put("version", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + limit?.let { put("limit", it.toString()) } + maxRootSpanId?.let { put("max_root_span_id", it) } + maxXactId?.let { put("max_xact_id", it) } + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -49,67 +106,42 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DatasetFetchParams && - this.datasetId == other.datasetId && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - datasetId, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "DatasetFetchParams{datasetId=$datasetId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetFetchParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetFetchParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null private var limit: Long? = null private var maxRootSpanId: String? = null private var maxXactId: String? = null private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(datasetFetchParams: DatasetFetchParams) = apply { - this.datasetId = datasetFetchParams.datasetId - this.limit = datasetFetchParams.limit - this.maxRootSpanId = datasetFetchParams.maxRootSpanId - this.maxXactId = datasetFetchParams.maxXactId - this.version = datasetFetchParams.version - additionalQueryParams(datasetFetchParams.additionalQueryParams) - additionalHeaders(datasetFetchParams.additionalHeaders) + datasetId = datasetFetchParams.datasetId + limit = datasetFetchParams.limit + maxRootSpanId = datasetFetchParams.maxRootSpanId + maxXactId = datasetFetchParams.maxXactId + version = datasetFetchParams.version + additionalHeaders = datasetFetchParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetFetchParams.additionalQueryParams.toBuilder() } /** Dataset id */ @@ -130,7 +162,17 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -144,7 +186,11 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { this.maxRootSpanId = maxRootSpanId } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -158,7 +204,10 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { this.maxXactId = maxXactId } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) /** * Retrieve a snapshot of events from a past time @@ -166,57 +215,143 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { this.version = version } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [DatasetFetchParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetFetchParams = DatasetFetchParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, + checkRequired("datasetId", datasetId), limit, maxRootSpanId, maxXactId, version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetFetchParams && datasetId == other.datasetId && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, limit, maxRootSpanId, maxXactId, version, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetFetchParams{datasetId=$datasetId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchPostParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchPostParams.kt index 7d3a72e7..b829eb13 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchPostParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetFetchPostParams.kt @@ -3,61 +3,162 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in a dataset. Equivalent to the GET form of the same path, but with the + * parameters in the request body rather than in the URL query. For more complex queries, use the + * `POST /btql` endpoint. + */ class DatasetFetchPostParams -constructor( +private constructor( private val datasetId: String, - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId - fun cursor(): Optional = Optional.ofNullable(cursor) - - fun filters(): Optional> = Optional.ofNullable(filters) - - fun limit(): Optional = Optional.ofNullable(limit) - - fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) - - fun maxXactId(): Optional = Optional.ofNullable(maxXactId) - - fun version(): Optional = Optional.ofNullable(version) - - @JvmSynthetic - internal fun getBody(): DatasetFetchPostBody { - return DatasetFetchPostBody( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * An opaque string to be used as a cursor for the next page of results, in order from latest to + * earliest. + * + * The string can be obtained directly from the `cursor` property of the previous fetch query + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun cursor(): Optional = body.cursor() + + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = body.limit() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxRootSpanId(): Optional = body.maxRootSpanId() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxXactId(): Optional = body.maxXactId() + + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = body.version() + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _cursor(): JsonField = body._cursor() + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _limit(): JsonField = body._limit() + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxRootSpanId(): JsonField = body._maxRootSpanId() + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxXactId(): JsonField = body._maxXactId() + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _version(): JsonField = body._version() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -66,39 +167,40 @@ constructor( } } - @JsonDeserialize(builder = DatasetFetchPostBody.Builder::class) @NoAutoDetect - class DatasetFetchPostBody - internal constructor( - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonProperty("limit") + @ExcludeMissing + private val limit: JsonField = JsonMissing.of(), + @JsonProperty("max_root_span_id") + @ExcludeMissing + private val maxRootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("max_xact_id") + @ExcludeMissing + private val maxXactId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * An opaque string to be used as a cursor for the next page of results, in order from * latest to earliest. * * The string can be obtained directly from the `cursor` property of the previous fetch * query - */ - @JsonProperty("cursor") fun cursor(): String? = cursor - - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("filters") fun filters(): List? = filters + fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) /** * limit the number of traces fetched @@ -114,8 +216,11 @@ constructor( * The `limit` parameter controls the number of full traces to return. So you may end up * with more individual rows than the specified limit if you are fetching events containing * traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("limit") fun limit(): Long? = limit + fun limit(): Optional = Optional.ofNullable(limit.getNullable("limit")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -128,8 +233,12 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_root_span_id") fun maxRootSpanId(): String? = maxRootSpanId + fun maxRootSpanId(): Optional = + Optional.ofNullable(maxRootSpanId.getNullable("max_root_span_id")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -142,81 +251,107 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_xact_id") fun maxXactId(): String? = maxXactId + fun maxXactId(): Optional = + Optional.ofNullable(maxXactId.getNullable("max_xact_id")) /** * Retrieve a snapshot of events from a past time * * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_root_span_id") + @ExcludeMissing + fun _maxRootSpanId(): JsonField = maxRootSpanId + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("max_xact_id") @ExcludeMissing fun _maxXactId(): JsonField = maxXactId + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("version") fun version(): String? = version + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is DatasetFetchPostBody && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalProperties, - ) - } - return hashCode + cursor() + limit() + maxRootSpanId() + maxXactId() + version() + validated = true } - override fun toString() = - "DatasetFetchPostBody{cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var cursor: String? = null - private var filters: List? = null - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null + private var cursor: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var maxRootSpanId: JsonField = JsonMissing.of() + private var maxXactId: JsonField = JsonMissing.of() + private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(datasetFetchPostBody: DatasetFetchPostBody) = apply { - this.cursor = datasetFetchPostBody.cursor - this.filters = datasetFetchPostBody.filters - this.limit = datasetFetchPostBody.limit - this.maxRootSpanId = datasetFetchPostBody.maxRootSpanId - this.maxXactId = datasetFetchPostBody.maxXactId - this.version = datasetFetchPostBody.version - additionalProperties(datasetFetchPostBody.additionalProperties) + internal fun from(body: Body) = apply { + cursor = body.cursor + limit = body.limit + maxRootSpanId = body.maxRootSpanId + maxXactId = body.maxXactId + version = body.version + additionalProperties = body.additionalProperties.toMutableMap() } /** @@ -226,18 +361,19 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - @JsonProperty("cursor") fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters - * are supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("filters") - fun filters(filters: List) = apply { this.filters = filters } + fun cursor(cursor: JsonField) = apply { this.cursor = cursor } /** * limit the number of traces fetched @@ -254,7 +390,26 @@ constructor( * with more individual rows than the specified limit if you are fetching events * containing traces. */ - @JsonProperty("limit") fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = limit(JsonField.ofNullable(limit)) + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -268,8 +423,23 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_root_span_id") - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = + maxRootSpanId(JsonField.ofNullable(maxRootSpanId)) + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + this.maxRootSpanId = maxRootSpanId + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -283,8 +453,19 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_xact_id") - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = maxXactId(JsonField.ofNullable(maxXactId)) + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxXactId(maxXactId: JsonField) = apply { this.maxXactId = maxXactId } /** * Retrieve a snapshot of events from a past time @@ -293,110 +474,103 @@ constructor( * use the `max_xact_id` returned by a past fetch as the version to reproduce that exact * fetch. */ - @JsonProperty("version") fun version(version: String) = apply { this.version = version } + fun version(version: String?) = version(JsonField.ofNullable(version)) + + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DatasetFetchPostBody = - DatasetFetchPostBody( + 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. + */ + fun build(): Body = + Body( cursor, - filters?.toUnmodifiable(), limit, maxRootSpanId, maxXactId, version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && cursor == other.cursor && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is DatasetFetchPostParams && - this.datasetId == other.datasetId && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(cursor, limit, maxRootSpanId, maxXactId, version, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - datasetId, - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "DatasetFetchPostParams{datasetId=$datasetId, cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{cursor=$cursor, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetFetchPostParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetFetchPostParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var cursor: String? = null - private var filters: MutableList = mutableListOf() - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(datasetFetchPostParams: DatasetFetchPostParams) = apply { - this.datasetId = datasetFetchPostParams.datasetId - this.cursor = datasetFetchPostParams.cursor - this.filters(datasetFetchPostParams.filters ?: listOf()) - this.limit = datasetFetchPostParams.limit - this.maxRootSpanId = datasetFetchPostParams.maxRootSpanId - this.maxXactId = datasetFetchPostParams.maxXactId - this.version = datasetFetchPostParams.version - additionalQueryParams(datasetFetchPostParams.additionalQueryParams) - additionalHeaders(datasetFetchPostParams.additionalHeaders) - additionalBodyProperties(datasetFetchPostParams.additionalBodyProperties) + datasetId = datasetFetchPostParams.datasetId + body = datasetFetchPostParams.body.toBuilder() + additionalHeaders = datasetFetchPostParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetFetchPostParams.additionalQueryParams.toBuilder() } /** Dataset id */ @@ -409,30 +583,18 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = apply { body.cursor(cursor) } - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. - * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. - */ - fun filters(filters: List) = apply { - this.filters.clear() - this.filters.addAll(filters) - } + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun addFilter(filter: PathLookupFilter) = apply { this.filters.add(filter) } + fun cursor(cursor: JsonField) = apply { body.cursor(cursor) } /** * limit the number of traces fetched @@ -449,7 +611,25 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { body.limit(limit) } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { body.limit(limit) } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -463,7 +643,22 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { body.maxRootSpanId(maxRootSpanId) } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + body.maxRootSpanId(maxRootSpanId) + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -477,7 +672,19 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { body.maxXactId(maxXactId) } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxXactId(maxXactId: JsonField) = apply { body.maxXactId(maxXactId) } /** * Retrieve a snapshot of events from a past time @@ -485,74 +692,167 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { body.version(version) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { body.version(version) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [DatasetFetchPostParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetFetchPostParams = DatasetFetchPostParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - cursor, - if (filters.size == 0) null else filters.toUnmodifiable(), - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("datasetId", datasetId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetFetchPostParams && datasetId == other.datasetId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetFetchPostParams{datasetId=$datasetId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetInsertParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetInsertParams.kt index 8089fb3e..8ed1370b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetInsertParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetInsertParams.kt @@ -2,49 +2,63 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.BaseDeserializer -import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects -import java.util.Optional +/** Insert a set of events into the dataset */ class DatasetInsertParams -constructor( +private constructor( private val datasetId: String, - private val events: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId - fun events(): List = events + /** + * A list of dataset events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = body.events() - @JvmSynthetic - internal fun getBody(): DatasetInsertBody { - return DatasetInsertBody(events, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _events(): JsonField> = body._events() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + @JvmSynthetic internal fun _body(): Body = body - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -53,352 +67,361 @@ constructor( } } - @JsonDeserialize(builder = DatasetInsertBody.Builder::class) @NoAutoDetect - class DatasetInsertBody - internal constructor( - private val events: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of dataset events to insert */ - @JsonProperty("events") fun events(): List? = events + /** + * A list of dataset events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") + + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") + @ExcludeMissing + fun _events(): JsonField> = events @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is DatasetInsertBody && - this.events == other.events && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(events, additionalProperties) - } - return hashCode + events().forEach { it.validate() } + validated = true } - override fun toString() = - "DatasetInsertBody{events=$events, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var events: List? = null + private var events: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(datasetInsertBody: DatasetInsertBody) = apply { - this.events = datasetInsertBody.events - additionalProperties(datasetInsertBody.additionalProperties) + internal fun from(body: Body) = apply { + events = body.events.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of dataset events to insert */ - @JsonProperty("events") fun events(events: List) = apply { this.events = events } + fun events(events: List) = events(JsonField.of(events)) + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } + + /** + * Adds a single [InsertDatasetEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertDatasetEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DatasetInsertBody = - DatasetInsertBody( - checkNotNull(events) { "`events` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("events", events).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && events == other.events && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is DatasetInsertParams && - this.datasetId == other.datasetId && - this.events == other.events && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - datasetId, - events, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "DatasetInsertParams{datasetId=$datasetId, events=$events, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = "Body{events=$events, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetInsertParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetInsertParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var events: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(datasetInsertParams: DatasetInsertParams) = apply { - this.datasetId = datasetInsertParams.datasetId - this.events(datasetInsertParams.events) - additionalQueryParams(datasetInsertParams.additionalQueryParams) - additionalHeaders(datasetInsertParams.additionalHeaders) - additionalBodyProperties(datasetInsertParams.additionalBodyProperties) + datasetId = datasetInsertParams.datasetId + body = datasetInsertParams.body.toBuilder() + additionalHeaders = datasetInsertParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetInsertParams.additionalQueryParams.toBuilder() } /** Dataset id */ fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } /** A list of dataset events to insert */ - fun events(events: List) = apply { - this.events.clear() - this.events.addAll(events) - } - - /** A list of dataset events to insert */ - fun addEvent(event: Event) = apply { this.events.add(event) } + fun events(events: List) = apply { body.events(events) } + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun events(events: JsonField>) = apply { body.events(events) } + + /** + * Adds a single [InsertDatasetEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertDatasetEvent) = apply { body.addEvent(event) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): DatasetInsertParams = - DatasetInsertParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - checkNotNull(events) { "`events` is required but was not set" }.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(using = Event.Deserializer::class) - @JsonSerialize(using = Event.Serializer::class) - class Event - private constructor( - private val insertDatasetEventReplace: InsertDatasetEventReplace? = null, - private val insertDatasetEventMerge: InsertDatasetEventMerge? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - fun insertDatasetEventReplace(): Optional = - Optional.ofNullable(insertDatasetEventReplace) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun insertDatasetEventMerge(): Optional = - Optional.ofNullable(insertDatasetEventMerge) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun isInsertDatasetEventReplace(): Boolean = insertDatasetEventReplace != null + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - fun isInsertDatasetEventMerge(): Boolean = insertDatasetEventMerge != null + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - fun asInsertDatasetEventReplace(): InsertDatasetEventReplace = - insertDatasetEventReplace.getOrThrow("insertDatasetEventReplace") + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun asInsertDatasetEventMerge(): InsertDatasetEventMerge = - insertDatasetEventMerge.getOrThrow("insertDatasetEventMerge") + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun _json(): Optional = Optional.ofNullable(_json) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - fun accept(visitor: Visitor): T { - return when { - insertDatasetEventReplace != null -> - visitor.visitInsertDatasetEventReplace(insertDatasetEventReplace) - insertDatasetEventMerge != null -> - visitor.visitInsertDatasetEventMerge(insertDatasetEventMerge) - else -> visitor.unknown(_json) - } + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun validate(): Event = apply { - if (!validated) { - if (insertDatasetEventReplace == null && insertDatasetEventMerge == null) { - throw BraintrustInvalidDataException("Unknown Event: $_json") - } - insertDatasetEventReplace?.validate() - insertDatasetEventMerge?.validate() - validated = true - } + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - return other is Event && - this.insertDatasetEventReplace == other.insertDatasetEventReplace && - this.insertDatasetEventMerge == other.insertDatasetEventMerge + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - override fun hashCode(): Int { - return Objects.hash(insertDatasetEventReplace, insertDatasetEventMerge) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - override fun toString(): String { - return when { - insertDatasetEventReplace != null -> - "Event{insertDatasetEventReplace=$insertDatasetEventReplace}" - insertDatasetEventMerge != null -> - "Event{insertDatasetEventMerge=$insertDatasetEventMerge}" - _json != null -> "Event{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Event") - } + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - companion object { + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmStatic - fun ofInsertDatasetEventReplace(insertDatasetEventReplace: InsertDatasetEventReplace) = - Event(insertDatasetEventReplace = insertDatasetEventReplace) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic - fun ofInsertDatasetEventMerge(insertDatasetEventMerge: InsertDatasetEventMerge) = - Event(insertDatasetEventMerge = insertDatasetEventMerge) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - interface Visitor { - - fun visitInsertDatasetEventReplace( - insertDatasetEventReplace: InsertDatasetEventReplace - ): T - - fun visitInsertDatasetEventMerge(insertDatasetEventMerge: InsertDatasetEventMerge): T + /** + * Returns an immutable instance of [DatasetInsertParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): DatasetInsertParams = + DatasetInsertParams( + checkRequired("datasetId", datasetId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Event: $json") - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class Deserializer : BaseDeserializer(Event::class) { + return /* spotless:off */ other is DatasetInsertParams && datasetId == other.datasetId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - override fun ObjectCodec.deserialize(node: JsonNode): Event { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Event(insertDatasetEventReplace = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Event(insertDatasetEventMerge = it, _json = json) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - return Event(_json = json) - } - } - - class Serializer : BaseSerializer(Event::class) { - - override fun serialize( - value: Event, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.insertDatasetEventReplace != null -> - generator.writeObject(value.insertDatasetEventReplace) - value.insertDatasetEventMerge != null -> - generator.writeObject(value.insertDatasetEventMerge) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Event") - } - } - } - } + override fun toString() = + "DatasetInsertParams{datasetId=$datasetId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPage.kt index 5ad34048..51260d7d 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.DatasetService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all datasets. The datasets are sorted by creation date, with the most recently-created + * datasets coming first + */ class DatasetListPage private constructor( private val datasetsService: DatasetService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is DatasetListPage && - this.datasetsService == other.datasetsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is DatasetListPage && datasetsService == other.datasetsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - datasetsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetsService, params, response) /* spotless:on */ override fun toString() = "DatasetListPage{datasetsService=$datasetsService, params=$params, response=$response}" @@ -87,23 +84,18 @@ private constructor( @JvmStatic fun of(datasetsService: DatasetService, params: DatasetListParams, response: Response) = - DatasetListPage( - datasetsService, - params, - response, - ) + DatasetListPage(datasetsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -113,11 +105,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -127,20 +123,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "DatasetListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [DatasetListPage]. */ @JvmStatic fun builder() = Builder() } @@ -157,22 +150,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: DatasetListPage, - ) : Iterable { + class AutoPager(private val firstPage: DatasetListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -181,7 +174,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPageAsync.kt index ab1096f7..7e0a0e47 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.DatasetServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all datasets. The datasets are sorted by creation date, with the most recently-created + * datasets coming first + */ class DatasetListPageAsync private constructor( private val datasetsService: DatasetServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is DatasetListPageAsync && - this.datasetsService == other.datasetsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is DatasetListPageAsync && datasetsService == other.datasetsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - datasetsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetsService, params, response) /* spotless:on */ override fun toString() = "DatasetListPageAsync{datasetsService=$datasetsService, params=$params, response=$response}" @@ -92,25 +88,19 @@ private constructor( fun of( datasetsService: DatasetServiceAsync, params: DatasetListParams, - response: Response - ) = - DatasetListPageAsync( - datasetsService, - params, - response, - ) + response: Response, + ) = DatasetListPageAsync(datasetsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +110,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +128,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "DatasetListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [DatasetListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -164,27 +155,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: DatasetListPageAsync, - ) { + class AutoPager(private val firstPage: DatasetListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Dataset) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +184,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListParams.kt index d42871f3..90416929 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all datasets. The datasets are sorted by creation date, with the most recently-created + * datasets coming first + */ class DatasetListParams -constructor( +private constructor( private val datasetName: String?, private val endingBefore: String?, private val ids: Ids?, @@ -30,92 +36,93 @@ constructor( private val projectId: String?, private val projectName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Name of the dataset to search for */ fun datasetName(): Optional = Optional.ofNullable(datasetName) + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.datasetName?.let { params.put("dataset_name", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DatasetListParams && - this.datasetName == other.datasetName && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - datasetName, - endingBefore, - ids, - limit, - orgName, - projectId, - projectName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "DatasetListParams{datasetName=$datasetName, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + datasetName?.let { put("dataset_name", it) } + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): DatasetListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [DatasetListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetName: String? = null private var endingBefore: String? = null @@ -125,25 +132,28 @@ constructor( private var projectId: String? = null private var projectName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(datasetListParams: DatasetListParams) = apply { - this.datasetName = datasetListParams.datasetName - this.endingBefore = datasetListParams.endingBefore - this.ids = datasetListParams.ids - this.limit = datasetListParams.limit - this.orgName = datasetListParams.orgName - this.projectId = datasetListParams.projectId - this.projectName = datasetListParams.projectName - this.startingAfter = datasetListParams.startingAfter - additionalQueryParams(datasetListParams.additionalQueryParams) - additionalHeaders(datasetListParams.additionalHeaders) + datasetName = datasetListParams.datasetName + endingBefore = datasetListParams.endingBefore + ids = datasetListParams.ids + limit = datasetListParams.limit + orgName = datasetListParams.orgName + projectId = datasetListParams.projectId + projectName = datasetListParams.projectName + startingAfter = datasetListParams.startingAfter + additionalHeaders = datasetListParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetListParams.additionalQueryParams.toBuilder() } /** Name of the dataset to search for */ - fun datasetName(datasetName: String) = apply { this.datasetName = datasetName } + fun datasetName(datasetName: String?) = apply { this.datasetName = datasetName } + + /** Alias for calling [Builder.datasetName] with `datasetName.orElse(null)`. */ + fun datasetName(datasetName: Optional) = datasetName(datasetName.getOrNull()) /** * Pagination cursor id. @@ -152,37 +162,56 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** * Pagination cursor id. @@ -191,48 +220,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [DatasetListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): DatasetListParams = DatasetListParams( datasetName, @@ -243,11 +339,15 @@ constructor( projectId, projectName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -257,8 +357,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -281,35 +379,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -318,21 +404,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -344,12 +441,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -360,4 +457,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetListParams && datasetName == other.datasetName && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetName, endingBefore, ids, limit, orgName, projectId, projectName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetListParams{datasetName=$datasetName, endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetRetrieveParams.kt index 963469a6..ef2657ae 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a dataset object by its id */ class DatasetRetrieveParams -constructor( +private constructor( private val datasetId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DatasetRetrieveParams && - this.datasetId == other.datasetId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - datasetId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "DatasetRetrieveParams{datasetId=$datasetId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetRetrieveParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(datasetRetrieveParams: DatasetRetrieveParams) = apply { - this.datasetId = datasetRetrieveParams.datasetId - additionalQueryParams(datasetRetrieveParams.additionalQueryParams) - additionalHeaders(datasetRetrieveParams.additionalHeaders) + datasetId = datasetRetrieveParams.datasetId + additionalHeaders = datasetRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetRetrieveParams.additionalQueryParams.toBuilder() } /** Dataset id */ fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [DatasetRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetRetrieveParams = DatasetRetrieveParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("datasetId", datasetId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetRetrieveParams && datasetId == other.datasetId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetRetrieveParams{datasetId=$datasetId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetSummarizeParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetSummarizeParams.kt index 434a6d19..d188b51b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetSummarizeParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetSummarizeParams.kt @@ -3,32 +3,42 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Summarize dataset */ class DatasetSummarizeParams -constructor( +private constructor( private val datasetId: String, private val summarizeData: Boolean?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId + /** Whether to summarize the data. If false (or omitted), only the metadata will be returned. */ fun summarizeData(): Optional = Optional.ofNullable(summarizeData) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.summarizeData?.let { params.put("summarize_data", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + summarizeData?.let { put("summarize_data", it.toString()) } + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -37,55 +47,36 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is DatasetSummarizeParams && - this.datasetId == other.datasetId && - this.summarizeData == other.summarizeData && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - datasetId, - summarizeData, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "DatasetSummarizeParams{datasetId=$datasetId, summarizeData=$summarizeData, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetSummarizeParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetSummarizeParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null private var summarizeData: Boolean? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(datasetSummarizeParams: DatasetSummarizeParams) = apply { - this.datasetId = datasetSummarizeParams.datasetId - this.summarizeData = datasetSummarizeParams.summarizeData - additionalQueryParams(datasetSummarizeParams.additionalQueryParams) - additionalHeaders(datasetSummarizeParams.additionalHeaders) + datasetId = datasetSummarizeParams.datasetId + summarizeData = datasetSummarizeParams.summarizeData + additionalHeaders = datasetSummarizeParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetSummarizeParams.additionalQueryParams.toBuilder() } /** Dataset id */ @@ -94,54 +85,148 @@ constructor( /** * Whether to summarize the data. If false (or omitted), only the metadata will be returned. */ - fun summarizeData(summarizeData: Boolean) = apply { this.summarizeData = summarizeData } + fun summarizeData(summarizeData: Boolean?) = apply { this.summarizeData = summarizeData } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** + * Alias for [Builder.summarizeData]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun summarizeData(summarizeData: Boolean) = summarizeData(summarizeData as Boolean?) + + /** Alias for calling [Builder.summarizeData] with `summarizeData.orElse(null)`. */ + fun summarizeData(summarizeData: Optional) = + summarizeData(summarizeData.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [DatasetSummarizeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetSummarizeParams = DatasetSummarizeParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, + checkRequired("datasetId", datasetId), summarizeData, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetSummarizeParams && datasetId == other.datasetId && summarizeData == other.summarizeData && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, summarizeData, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetSummarizeParams{datasetId=$datasetId, summarizeData=$summarizeData, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetUpdateParams.kt index 1ab15c86..038dc497 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/DatasetUpdateParams.kt @@ -3,49 +3,97 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a dataset object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class DatasetUpdateParams -constructor( +private constructor( private val datasetId: String, - private val description: String?, - private val metadata: Metadata?, - private val name: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Dataset id */ fun datasetId(): String = datasetId - fun description(): Optional = Optional.ofNullable(description) - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun name(): Optional = Optional.ofNullable(name) - - @JvmSynthetic - internal fun getBody(): DatasetUpdateBody { - return DatasetUpdateBody( - description, - metadata, - name, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Textual description of the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * User-controlled metadata about the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * Name of the dataset. Within a project, dataset names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * 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() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -54,321 +102,517 @@ constructor( } } - @JsonDeserialize(builder = DatasetUpdateBody.Builder::class) @NoAutoDetect - class DatasetUpdateBody - internal constructor( - private val description: String?, - private val metadata: Metadata?, - private val name: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Textual description of the dataset */ - @JsonProperty("description") fun description(): String? = description - - /** User-controlled metadata about the dataset */ - @JsonProperty("metadata") fun metadata(): Metadata? = metadata - - /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") fun name(): String? = name + /** + * Textual description of the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * User-controlled metadata about the dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Name of the dataset. Within a project, dataset names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is DatasetUpdateBody && - this.description == other.description && - this.metadata == other.metadata && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - description, - metadata, - name, - additionalProperties, - ) - } - return hashCode + description() + metadata().ifPresent { it.validate() } + name() + validated = true } - override fun toString() = - "DatasetUpdateBody{description=$description, metadata=$metadata, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var description: String? = null - private var metadata: Metadata? = null - private var name: String? = null + private var description: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(datasetUpdateBody: DatasetUpdateBody) = apply { - this.description = datasetUpdateBody.description - this.metadata = datasetUpdateBody.metadata - this.name = datasetUpdateBody.name - additionalProperties(datasetUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + description = body.description + metadata = body.metadata + name = body.name + additionalProperties = body.additionalProperties.toMutableMap() } /** Textual description of the dataset */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** User-controlled metadata about the dataset */ - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** Name of the dataset. Within a project, dataset names are unique */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): DatasetUpdateBody = - DatasetUpdateBody( - description, - metadata, - name, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(description, metadata, name, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && description == other.description && metadata == other.metadata && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is DatasetUpdateParams && - this.datasetId == other.datasetId && - this.description == other.description && - this.metadata == other.metadata && - this.name == other.name && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(description, metadata, name, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - datasetId, - description, - metadata, - name, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "DatasetUpdateParams{datasetId=$datasetId, description=$description, metadata=$metadata, name=$name, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{description=$description, metadata=$metadata, name=$name, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [DatasetUpdateParams]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [DatasetUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var datasetId: String? = null - private var description: String? = null - private var metadata: Metadata? = null - private var name: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(datasetUpdateParams: DatasetUpdateParams) = apply { - this.datasetId = datasetUpdateParams.datasetId - this.description = datasetUpdateParams.description - this.metadata = datasetUpdateParams.metadata - this.name = datasetUpdateParams.name - additionalQueryParams(datasetUpdateParams.additionalQueryParams) - additionalHeaders(datasetUpdateParams.additionalHeaders) - additionalBodyProperties(datasetUpdateParams.additionalBodyProperties) + datasetId = datasetUpdateParams.datasetId + body = datasetUpdateParams.body.toBuilder() + additionalHeaders = datasetUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = datasetUpdateParams.additionalQueryParams.toBuilder() } /** Dataset id */ fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } /** Textual description of the dataset */ - fun description(description: String) = apply { this.description = description } + 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) } /** User-controlled metadata about the dataset */ - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** Name of the dataset. Within a project, dataset names are unique */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * 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) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [DatasetUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): DatasetUpdateParams = DatasetUpdateParams( - checkNotNull(datasetId) { "`datasetId` is required but was not set" }, - description, - metadata, - name, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("datasetId", datasetId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } /** User-controlled metadata about the dataset */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is DatasetUpdateParams && datasetId == other.datasetId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "DatasetUpdateParams{datasetId=$datasetId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVar.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVar.kt index 73e03e71..739d7149 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVar.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVar.kt @@ -8,264 +8,370 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = EnvVar.Builder::class) @NoAutoDetect class EnvVar +@JsonCreator private constructor( - private val id: JsonField, - private val objectType: JsonField, - private val objectId: JsonField, - private val name: JsonField, - private val created: JsonField, - private val used: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("used") + @ExcludeMissing + private val used: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the environment variable */ + /** + * Unique identifier for the environment variable + * + * @throws BraintrustInvalidDataException 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 type of the object the environment variable is scoped for */ - fun objectType(): ObjectType = objectType.getRequired("object_type") + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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") - /** The id of the object the environment variable is scoped for */ + /** + * The id of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** The name of the environment variable */ - fun name(): String = name.getRequired("name") + /** + * The type of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") - /** Date of environment variable creation */ + /** + * Date of environment variable creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Date the environment variable was last used */ + /** + * Date the environment variable was last used + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun used(): Optional = Optional.ofNullable(used.getNullable("used")) - /** Unique identifier for the environment variable */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") @ExcludeMissing fun _objectType() = objectType - - /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") @ExcludeMissing fun _objectId() = objectId - - /** The name of the environment variable */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Date of environment variable creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Date the environment variable was last used */ - @JsonProperty("used") @ExcludeMissing fun _used() = used + /** + * 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 [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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [used]. + * + * Unlike [used], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("used") @ExcludeMissing fun _used(): JsonField = used @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): EnvVar = apply { - if (!validated) { - id() - objectType() - objectId() - name() - created() - used() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): EnvVar = apply { + if (validated) { + return@apply } - return other is EnvVar && - this.id == other.id && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.name == other.name && - this.created == other.created && - this.used == other.used && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - objectType, - objectId, - name, - created, - used, - additionalProperties, - ) - } - return hashCode + id() + name() + objectId() + objectType() + created() + used() + validated = true } - override fun toString() = - "EnvVar{id=$id, objectType=$objectType, objectId=$objectId, name=$name, created=$created, used=$used, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVar]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [EnvVar]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var objectType: JsonField = JsonMissing.of() - private var objectId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null private var created: JsonField = JsonMissing.of() private var used: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(envVar: EnvVar) = apply { - this.id = envVar.id - this.objectType = envVar.objectType - this.objectId = envVar.objectId - this.name = envVar.name - this.created = envVar.created - this.used = envVar.used - additionalProperties(envVar.additionalProperties) + id = envVar.id + name = envVar.name + objectId = envVar.objectId + objectType = envVar.objectType + created = envVar.created + used = envVar.used + additionalProperties = envVar.additionalProperties.toMutableMap() } /** Unique identifier for the environment variable */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the environment variable */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } - /** The type of the object the environment variable is scoped for */ - fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + /** The name of the environment variable */ + fun name(name: String) = name(JsonField.of(name)) - /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") - @ExcludeMissing - fun objectType(objectType: JsonField) = apply { this.objectType = objectType } + /** + * 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 } /** The id of the object the environment variable is scoped for */ fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") - @ExcludeMissing + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun objectId(objectId: JsonField) = apply { this.objectId = objectId } - /** The name of the environment variable */ - fun name(name: String) = name(JsonField.of(name)) - - /** The name of the environment variable */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** The type of the object the environment variable is scoped for */ + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) - /** Date of environment variable creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { this.objectType = objectType } /** Date of environment variable creation */ - @JsonProperty("created") - @ExcludeMissing + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } /** Date the environment variable was last used */ - fun used(used: OffsetDateTime) = used(JsonField.of(used)) - - /** Date the environment variable was last used */ - @JsonProperty("used") - @ExcludeMissing + fun used(used: OffsetDateTime?) = used(JsonField.ofNullable(used)) + + /** Alias for calling [Builder.used] with `used.orElse(null)`. */ + fun used(used: Optional) = used(used.getOrNull()) + + /** + * Sets [Builder.used] to an arbitrary JSON value. + * + * You should usually call [Builder.used] with a well-typed [OffsetDateTime] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun used(used: JsonField) = apply { this.used = used } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [EnvVar]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): EnvVar = EnvVar( - id, - objectType, - objectId, - name, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), created, used, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + /** The type of the object the environment variable is scoped for */ + class ObjectType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + @JvmField val ORGANIZATION = of("organization") - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + @JvmField val PROJECT = of("project") - @JvmField val FUNCTION = ObjectType(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) } + /** An enum containing [ObjectType]'s known values. */ enum class Known { ORGANIZATION, PROJECT, FUNCTION, } + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { ORGANIZATION, PROJECT, FUNCTION, + /** + * An enum member indicating that [ObjectType] 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) { ORGANIZATION -> Value.ORGANIZATION @@ -274,6 +380,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { ORGANIZATION -> Known.ORGANIZATION @@ -282,6 +397,47 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVar && id == other.id && name == other.name && objectId == other.objectId && objectType == other.objectType && created == other.created && used == other.used && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, objectId, objectType, created, used, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EnvVar{id=$id, name=$name, objectId=$objectId, objectType=$objectType, created=$created, used=$used, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarCreateParams.kt index 4b7c486e..ba236659 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarCreateParams.kt @@ -5,362 +5,632 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new env_var. If there is an existing env_var with the same name as the one specified in + * the request, will return the existing env_var unmodified + */ class EnvVarCreateParams -constructor( - private val name: String, - private val objectId: String, - private val objectType: ObjectType, - private val value: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun value(): Optional = Optional.ofNullable(value) - - @JvmSynthetic - internal fun getBody(): EnvVarCreateBody { - return EnvVarCreateBody( - name, - objectId, - objectType, - value, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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() + + /** + * The id of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The type of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = body.objectType() + + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun value(): Optional = body.value() + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _value(): JsonField = body._value() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = EnvVarCreateBody.Builder::class) @NoAutoDetect - class EnvVarCreateBody - internal constructor( - private val name: String?, - private val objectId: String?, - private val objectType: ObjectType?, - private val value: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + private val value: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The name of the environment variable */ - @JsonProperty("name") fun name(): String? = name - - /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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") + + /** + * The id of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The type of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") + + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = Optional.ofNullable(value.getNullable("value")) + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType - /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(): String? = value + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is EnvVarCreateBody && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.value == other.value && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - objectId, - objectType, - value, - additionalProperties, - ) - } - return hashCode + name() + objectId() + objectType() + value() + validated = true } - override fun toString() = - "EnvVarCreateBody{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalProperties=$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() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var value: String? = null + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(envVarCreateBody: EnvVarCreateBody) = apply { - this.name = envVarCreateBody.name - this.objectId = envVarCreateBody.objectId - this.objectType = envVarCreateBody.objectType - this.value = envVarCreateBody.value - additionalProperties(envVarCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + objectId = body.objectId + objectType = body.objectType + value = body.value + additionalProperties = body.additionalProperties.toMutableMap() } /** The name of the environment variable */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(value: String) = apply { this.value = value } + fun value(value: String?) = value(JsonField.ofNullable(value)) + + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): EnvVarCreateBody = - EnvVarCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, + 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() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), value, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && objectId == other.objectId && objectType == other.objectType && value == other.value && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is EnvVarCreateParams && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.value == other.value && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, objectId, objectType, value, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - objectId, - objectType, - value, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "EnvVarCreateParams{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var value: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(envVarCreateParams: EnvVarCreateParams) = apply { - this.name = envVarCreateParams.name - this.objectId = envVarCreateParams.objectId - this.objectType = envVarCreateParams.objectType - this.value = envVarCreateParams.value - additionalQueryParams(envVarCreateParams.additionalQueryParams) - additionalHeaders(envVarCreateParams.additionalHeaders) - additionalBodyProperties(envVarCreateParams.additionalBodyProperties) + body = envVarCreateParams.body.toBuilder() + additionalHeaders = envVarCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarCreateParams.additionalQueryParams.toBuilder() } /** The name of the environment variable */ - fun name(name: String) = apply { this.name = 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) } /** The id of the object the environment variable is scoped for */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The type of the object the environment variable is scoped for */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: ObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** The value of the environment variable. Will be encrypted at rest. */ - fun value(value: String) = apply { this.value = value } + fun value(value: String?) = apply { body.value(value) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun value(value: JsonField) = apply { body.value(value) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + this.additionalQueryParams.putAll(additionalQueryParams) } - fun build(): EnvVarCreateParams = - EnvVarCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - value, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - return other is ObjectType && this.value == other.value + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [EnvVarCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvVarCreateParams = + EnvVarCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - override fun toString() = value.toString() + /** The type of the object the environment variable is scoped for */ + class ObjectType @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 ORGANIZATION = ObjectType(JsonField.of("organization")) + @JvmField val ORGANIZATION = of("organization") - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + @JvmField val PROJECT = of("project") - @JvmField val FUNCTION = ObjectType(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) } + /** An enum containing [ObjectType]'s known values. */ enum class Known { ORGANIZATION, PROJECT, FUNCTION, } + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { ORGANIZATION, PROJECT, FUNCTION, + /** + * An enum member indicating that [ObjectType] 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) { ORGANIZATION -> Value.ORGANIZATION @@ -369,6 +639,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { ORGANIZATION -> Known.ORGANIZATION @@ -377,6 +656,43 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "EnvVarCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarDeleteParams.kt index 358a7d95..8675b2e0 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an env_var object by its id */ class EnvVarDeleteParams -constructor( +private constructor( private val envVarId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** EnvVar id */ fun envVarId(): String = envVarId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is EnvVarDeleteParams && - this.envVarId == other.envVarId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - envVarId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "EnvVarDeleteParams{envVarId=$envVarId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarDeleteParams]. + * + * The following fields are required: + * ```java + * .envVarId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var envVarId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(envVarDeleteParams: EnvVarDeleteParams) = apply { - this.envVarId = envVarDeleteParams.envVarId - additionalQueryParams(envVarDeleteParams.additionalQueryParams) - additionalHeaders(envVarDeleteParams.additionalHeaders) - additionalBodyProperties(envVarDeleteParams.additionalBodyProperties) + envVarId = envVarDeleteParams.envVarId + additionalHeaders = envVarDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = envVarDeleteParams.additionalBodyProperties.toMutableMap() } /** EnvVar id */ fun envVarId(envVarId: String) = apply { this.envVarId = envVarId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [EnvVarDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .envVarId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): EnvVarDeleteParams = EnvVarDeleteParams( - checkNotNull(envVarId) { "`envVarId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("envVarId", envVarId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarDeleteParams && envVarId == other.envVarId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(envVarId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "EnvVarDeleteParams{envVarId=$envVarId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListParams.kt index 4f26f91e..4977d934 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListParams.kt @@ -4,15 +4,13 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -22,175 +20,251 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all env_vars. The env_vars are sorted by creation date, with the most recently-created + * env_vars coming first + */ class EnvVarListParams -constructor( +private constructor( private val envVarName: String?, private val ids: Ids?, private val limit: Long?, private val objectId: String?, - private val objectType: ObjectType?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val objectType: EnvVarObjectType?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Name of the env_var to search for */ fun envVarName(): Optional = Optional.ofNullable(envVarName) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** The id of the object the environment variable is scoped for */ fun objectId(): Optional = Optional.ofNullable(objectId) - fun objectType(): Optional = Optional.ofNullable(objectType) - - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.envVarName?.let { params.put("env_var_name", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.objectId?.let { params.put("object_id", listOf(it.toString())) } - this.objectType?.let { params.put("object_type", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is EnvVarListParams && - this.envVarName == other.envVarName && - this.ids == other.ids && - this.limit == other.limit && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - envVarName, - ids, - limit, - objectId, - objectType, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "EnvVarListParams{envVarName=$envVarName, ids=$ids, limit=$limit, objectId=$objectId, objectType=$objectType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + /** The type of the object the environment variable is scoped for */ + fun objectType(): Optional = Optional.ofNullable(objectType) + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + envVarName?.let { put("env_var_name", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + objectId?.let { put("object_id", it) } + objectType?.let { put("object_type", it.asString()) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): EnvVarListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [EnvVarListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var envVarName: String? = null private var ids: Ids? = null private var limit: Long? = null private var objectId: String? = null - private var objectType: ObjectType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var objectType: EnvVarObjectType? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(envVarListParams: EnvVarListParams) = apply { - this.envVarName = envVarListParams.envVarName - this.ids = envVarListParams.ids - this.limit = envVarListParams.limit - this.objectId = envVarListParams.objectId - this.objectType = envVarListParams.objectType - additionalQueryParams(envVarListParams.additionalQueryParams) - additionalHeaders(envVarListParams.additionalHeaders) + envVarName = envVarListParams.envVarName + ids = envVarListParams.ids + limit = envVarListParams.limit + objectId = envVarListParams.objectId + objectType = envVarListParams.objectType + additionalHeaders = envVarListParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarListParams.additionalQueryParams.toBuilder() } /** Name of the env_var to search for */ - fun envVarName(envVarName: String) = apply { this.envVarName = envVarName } + fun envVarName(envVarName: String?) = apply { this.envVarName = envVarName } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.envVarName] with `envVarName.orElse(null)`. */ + fun envVarName(envVarName: Optional) = envVarName(envVarName.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** The id of the object the environment variable is scoped for */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String?) = apply { this.objectId = objectId } + + /** Alias for calling [Builder.objectId] with `objectId.orElse(null)`. */ + fun objectId(objectId: Optional) = objectId(objectId.getOrNull()) /** The type of the object the environment variable is scoped for */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: EnvVarObjectType?) = apply { this.objectType = objectType } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.objectType] with `objectType.orElse(null)`. */ + fun objectType(objectType: Optional) = objectType(objectType.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [EnvVarListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): EnvVarListParams = EnvVarListParams( envVarName, @@ -198,11 +272,15 @@ constructor( limit, objectId, objectType, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -212,8 +290,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -236,35 +312,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -273,21 +337,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -299,12 +374,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -316,66 +391,16 @@ constructor( } } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val FUNCTION = ObjectType(JsonField.of("function")) - - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - FUNCTION, - } - - enum class Value { - ORGANIZATION, - PROJECT, - FUNCTION, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - FUNCTION -> Value.FUNCTION - else -> Value._UNKNOWN - } + return /* spotless:off */ other is EnvVarListParams && envVarName == other.envVarName && ids == other.ids && limit == other.limit && objectId == other.objectId && objectType == other.objectType && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - FUNCTION -> Known.FUNCTION - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(envVarName, ids, limit, objectId, objectType, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "EnvVarListParams{envVarName=$envVarName, ids=$ids, limit=$limit, objectId=$objectId, objectType=$objectType, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListResponse.kt index 2232c807..dc10c986 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarListResponse.kt @@ -7,106 +7,162 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects -@JsonDeserialize(builder = EnvVarListResponse.Builder::class) @NoAutoDetect class EnvVarListResponse +@JsonCreator private constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + @ExcludeMissing + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** A list of env_var objects */ + /** + * A list of env_var objects + * + * @throws BraintrustInvalidDataException 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 objects(): List = objects.getRequired("objects") - /** A list of env_var objects */ - @JsonProperty("objects") @ExcludeMissing fun _objects() = objects + /** + * Returns the raw JSON value of [objects]. + * + * Unlike [objects], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("objects") @ExcludeMissing fun _objects(): JsonField> = objects @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): EnvVarListResponse = apply { - if (!validated) { - objects().forEach { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): EnvVarListResponse = apply { + if (validated) { + return@apply } - return other is EnvVarListResponse && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(objects, additionalProperties) - } - return hashCode + objects().forEach { it.validate() } + validated = true } - override fun toString() = - "EnvVarListResponse{objects=$objects, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarListResponse]. + * + * The following fields are required: + * ```java + * .objects() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [EnvVarListResponse]. */ + class Builder internal constructor() { - private var objects: JsonField> = JsonMissing.of() + private var objects: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(envVarListResponse: EnvVarListResponse) = apply { - this.objects = envVarListResponse.objects - additionalProperties(envVarListResponse.additionalProperties) + objects = envVarListResponse.objects.map { it.toMutableList() } + additionalProperties = envVarListResponse.additionalProperties.toMutableMap() } /** A list of env_var objects */ fun objects(objects: List) = objects(JsonField.of(objects)) - /** A list of env_var objects */ - @JsonProperty("objects") - @ExcludeMissing - fun objects(objects: JsonField>) = apply { this.objects = objects } + /** + * Sets [Builder.objects] to an arbitrary JSON value. + * + * You should usually call [Builder.objects] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun objects(objects: JsonField>) = apply { + this.objects = objects.map { it.toMutableList() } + } + + /** + * Adds a single [EnvVar] to [objects]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addObject(object_: EnvVar) = apply { + objects = + (objects ?: JsonField.of(mutableListOf())).also { + checkKnown("objects", it).add(object_) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [EnvVarListResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objects() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): EnvVarListResponse = EnvVarListResponse( - objects.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable() + checkRequired("objects", objects).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarListResponse && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objects, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EnvVarListResponse{objects=$objects, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarObjectType.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarObjectType.kt new file mode 100644 index 00000000..b78e5292 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarObjectType.kt @@ -0,0 +1,115 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +/** The type of the object the environment variable is scoped for */ +class EnvVarObjectType @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 ORGANIZATION = of("organization") + + @JvmField val PROJECT = of("project") + + @JvmField val FUNCTION = of("function") + + @JvmStatic fun of(value: String) = EnvVarObjectType(JsonField.of(value)) + } + + /** An enum containing [EnvVarObjectType]'s known values. */ + enum class Known { + ORGANIZATION, + PROJECT, + FUNCTION, + } + + /** + * An enum containing [EnvVarObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EnvVarObjectType] 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 { + ORGANIZATION, + PROJECT, + FUNCTION, + /** + * An enum member indicating that [EnvVarObjectType] 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) { + ORGANIZATION -> Value.ORGANIZATION + PROJECT -> Value.PROJECT + FUNCTION -> Value.FUNCTION + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ORGANIZATION -> Known.ORGANIZATION + PROJECT -> Known.PROJECT + FUNCTION -> Known.FUNCTION + else -> throw BraintrustInvalidDataException("Unknown EnvVarObjectType: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarReplaceParams.kt index b14cc253..4c9da803 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarReplaceParams.kt @@ -5,362 +5,632 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace env_var. If there is an existing env_var with the same name as the one + * specified in the request, will replace the existing env_var with the provided fields + */ class EnvVarReplaceParams -constructor( - private val name: String, - private val objectId: String, - private val objectType: ObjectType, - private val value: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun value(): Optional = Optional.ofNullable(value) - - @JvmSynthetic - internal fun getBody(): EnvVarReplaceBody { - return EnvVarReplaceBody( - name, - objectId, - objectType, - value, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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() + + /** + * The id of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The type of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = body.objectType() + + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun value(): Optional = body.value() + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _value(): JsonField = body._value() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = EnvVarReplaceBody.Builder::class) @NoAutoDetect - class EnvVarReplaceBody - internal constructor( - private val name: String?, - private val objectId: String?, - private val objectType: ObjectType?, - private val value: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + private val value: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The name of the environment variable */ - @JsonProperty("name") fun name(): String? = name - - /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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") + + /** + * The id of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The type of the object the environment variable is scoped for + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") + + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = Optional.ofNullable(value.getNullable("value")) + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType - /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(): String? = value + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is EnvVarReplaceBody && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.value == other.value && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - objectId, - objectType, - value, - additionalProperties, - ) - } - return hashCode + name() + objectId() + objectType() + value() + validated = true } - override fun toString() = - "EnvVarReplaceBody{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalProperties=$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() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var value: String? = null + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(envVarReplaceBody: EnvVarReplaceBody) = apply { - this.name = envVarReplaceBody.name - this.objectId = envVarReplaceBody.objectId - this.objectType = envVarReplaceBody.objectType - this.value = envVarReplaceBody.value - additionalProperties(envVarReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + objectId = body.objectId + objectType = body.objectType + value = body.value + additionalProperties = body.additionalProperties.toMutableMap() } /** The name of the environment variable */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** The id of the object the environment variable is scoped for */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The type of the object the environment variable is scoped for */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(value: String) = apply { this.value = value } + fun value(value: String?) = value(JsonField.ofNullable(value)) + + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): EnvVarReplaceBody = - EnvVarReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, + 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() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), value, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && objectId == other.objectId && objectType == other.objectType && value == other.value && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is EnvVarReplaceParams && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.value == other.value && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, objectId, objectType, value, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - objectId, - objectType, - value, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "EnvVarReplaceParams{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, objectId=$objectId, objectType=$objectType, value=$value, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarReplaceParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var value: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(envVarReplaceParams: EnvVarReplaceParams) = apply { - this.name = envVarReplaceParams.name - this.objectId = envVarReplaceParams.objectId - this.objectType = envVarReplaceParams.objectType - this.value = envVarReplaceParams.value - additionalQueryParams(envVarReplaceParams.additionalQueryParams) - additionalHeaders(envVarReplaceParams.additionalHeaders) - additionalBodyProperties(envVarReplaceParams.additionalBodyProperties) + body = envVarReplaceParams.body.toBuilder() + additionalHeaders = envVarReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarReplaceParams.additionalQueryParams.toBuilder() } /** The name of the environment variable */ - fun name(name: String) = apply { this.name = 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) } /** The id of the object the environment variable is scoped for */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The type of the object the environment variable is scoped for */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: ObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** The value of the environment variable. Will be encrypted at rest. */ - fun value(value: String) = apply { this.value = value } + fun value(value: String?) = apply { body.value(value) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun value(value: JsonField) = apply { body.value(value) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + this.additionalQueryParams.putAll(additionalQueryParams) } - fun build(): EnvVarReplaceParams = - EnvVarReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - value, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - return other is ObjectType && this.value == other.value + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [EnvVarReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EnvVarReplaceParams = + EnvVarReplaceParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - override fun toString() = value.toString() + /** The type of the object the environment variable is scoped for */ + class ObjectType @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 ORGANIZATION = ObjectType(JsonField.of("organization")) + @JvmField val ORGANIZATION = of("organization") - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + @JvmField val PROJECT = of("project") - @JvmField val FUNCTION = ObjectType(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) } + /** An enum containing [ObjectType]'s known values. */ enum class Known { ORGANIZATION, PROJECT, FUNCTION, } + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { ORGANIZATION, PROJECT, FUNCTION, + /** + * An enum member indicating that [ObjectType] 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) { ORGANIZATION -> Value.ORGANIZATION @@ -369,6 +639,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { ORGANIZATION -> Known.ORGANIZATION @@ -377,6 +656,43 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "EnvVarReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParams.kt index 4c26e77c..588b7b7c 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an env_var object by its id */ class EnvVarRetrieveParams -constructor( +private constructor( private val envVarId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** EnvVar id */ fun envVarId(): String = envVarId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is EnvVarRetrieveParams && - this.envVarId == other.envVarId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - envVarId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "EnvVarRetrieveParams{envVarId=$envVarId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarRetrieveParams]. + * + * The following fields are required: + * ```java + * .envVarId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var envVarId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(envVarRetrieveParams: EnvVarRetrieveParams) = apply { - this.envVarId = envVarRetrieveParams.envVarId - additionalQueryParams(envVarRetrieveParams.additionalQueryParams) - additionalHeaders(envVarRetrieveParams.additionalHeaders) + envVarId = envVarRetrieveParams.envVarId + additionalHeaders = envVarRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarRetrieveParams.additionalQueryParams.toBuilder() } /** EnvVar id */ fun envVarId(envVarId: String) = apply { this.envVarId = envVarId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [EnvVarRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .envVarId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): EnvVarRetrieveParams = EnvVarRetrieveParams( - checkNotNull(envVarId) { "`envVarId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("envVarId", envVarId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarRetrieveParams && envVarId == other.envVarId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(envVarId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "EnvVarRetrieveParams{envVarId=$envVarId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarUpdateParams.kt index 8da2fd52..58ba35d3 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EnvVarUpdateParams.kt @@ -3,45 +3,82 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update an env_var object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class EnvVarUpdateParams -constructor( +private constructor( private val envVarId: String, - private val name: String, - private val value: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** EnvVar id */ fun envVarId(): String = envVarId - fun name(): String = name + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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() - fun value(): Optional = Optional.ofNullable(value) + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun value(): Optional = body.value() - @JvmSynthetic - internal fun getBody(): EnvVarUpdateBody { - return EnvVarUpdateBody( - name, - value, - additionalBodyProperties, - ) - } + /** + * 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 [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _value(): JsonField = body._value() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -50,234 +87,385 @@ constructor( } } - @JsonDeserialize(builder = EnvVarUpdateBody.Builder::class) @NoAutoDetect - class EnvVarUpdateBody - internal constructor( - private val name: String?, - private val value: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("value") + @ExcludeMissing + private val value: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The name of the environment variable */ - @JsonProperty("name") fun name(): String? = name - - /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(): String? = value + /** + * The name of the environment variable + * + * @throws BraintrustInvalidDataException 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") + + /** + * The value of the environment variable. Will be encrypted at rest. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun value(): Optional = Optional.ofNullable(value.getNullable("value")) + + /** + * 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 [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is EnvVarUpdateBody && - this.name == other.name && - this.value == other.value && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - value, - additionalProperties, - ) - } - return hashCode + name() + value() + validated = true } - override fun toString() = - "EnvVarUpdateBody{name=$name, value=$value, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var value: String? = null + private var name: JsonField? = null + private var value: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(envVarUpdateBody: EnvVarUpdateBody) = apply { - this.name = envVarUpdateBody.name - this.value = envVarUpdateBody.value - additionalProperties(envVarUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + value = body.value + additionalProperties = body.additionalProperties.toMutableMap() } /** The name of the environment variable */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** The value of the environment variable. Will be encrypted at rest. */ - @JsonProperty("value") fun value(value: String) = apply { this.value = value } + fun value(value: String?) = value(JsonField.ofNullable(value)) + + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun value(value: JsonField) = apply { this.value = value } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): EnvVarUpdateBody = - EnvVarUpdateBody( - checkNotNull(name) { "`name` is required but was not set" }, - value, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * 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), value, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && value == other.value && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is EnvVarUpdateParams && - this.envVarId == other.envVarId && - this.name == other.name && - this.value == other.value && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, value, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - envVarId, - name, - value, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "EnvVarUpdateParams{envVarId=$envVarId, name=$name, value=$value, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, value=$value, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [EnvVarUpdateParams]. + * + * The following fields are required: + * ```java + * .envVarId() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [EnvVarUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var envVarId: String? = null - private var name: String? = null - private var value: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(envVarUpdateParams: EnvVarUpdateParams) = apply { - this.envVarId = envVarUpdateParams.envVarId - this.name = envVarUpdateParams.name - this.value = envVarUpdateParams.value - additionalQueryParams(envVarUpdateParams.additionalQueryParams) - additionalHeaders(envVarUpdateParams.additionalHeaders) - additionalBodyProperties(envVarUpdateParams.additionalBodyProperties) + envVarId = envVarUpdateParams.envVarId + body = envVarUpdateParams.body.toBuilder() + additionalHeaders = envVarUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = envVarUpdateParams.additionalQueryParams.toBuilder() } /** EnvVar id */ fun envVarId(envVarId: String) = apply { this.envVarId = envVarId } /** The name of the environment variable */ - fun name(name: String) = apply { this.name = 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) } /** The value of the environment variable. Will be encrypted at rest. */ - fun value(value: String) = apply { this.value = value } + fun value(value: String?) = apply { body.value(value) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.value] with `value.orElse(null)`. */ + fun value(value: Optional) = value(value.getOrNull()) + + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun value(value: JsonField) = apply { body.value(value) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [EnvVarUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .envVarId() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): EnvVarUpdateParams = EnvVarUpdateParams( - checkNotNull(envVarId) { "`envVarId` is required but was not set" }, - checkNotNull(name) { "`name` is required but was not set" }, - value, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("envVarId", envVarId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is EnvVarUpdateParams && envVarId == other.envVarId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(envVarId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "EnvVarUpdateParams{envVarId=$envVarId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EvalCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EvalCreateParams.kt index 31605b1c..96d00635 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EvalCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/EvalCreateParams.kt @@ -10,10 +10,15 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator @@ -27,771 +32,4247 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional - +import kotlin.jvm.optionals.getOrNull + +/** + * Launch an evaluation. This is the API-equivalent of the `Eval` function that is built into the + * Braintrust SDK. In the Eval API, you provide pointers to a dataset, task function, and scoring + * functions. The API will then run the evaluation, create an experiment, and return the results + * along with a link to the experiment. To learn more about evals, see the + * [Evals guide](https://www.braintrust.dev/docs/guides/evals). + */ class EvalCreateParams -constructor( - private val data: Data, - private val projectId: String, - private val scores: List, - private val task: Task, - private val experimentName: String?, - private val metadata: Metadata?, - private val stream: Boolean?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun data(): Data = data - - fun projectId(): String = projectId - - fun scores(): List = scores - - fun task(): Task = task - - fun experimentName(): Optional = Optional.ofNullable(experimentName) - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun stream(): Optional = Optional.ofNullable(stream) - - @JvmSynthetic - internal fun getBody(): EvalCreateBody { - return EvalCreateBody( - data, - projectId, - scores, - task, - experimentName, - metadata, - stream, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = EvalCreateBody.Builder::class) - @NoAutoDetect - class EvalCreateBody - internal constructor( - private val data: Data?, - private val projectId: String?, - private val scores: List?, - private val task: Task?, - private val experimentName: String?, - private val metadata: Metadata?, - private val stream: Boolean?, - private val additionalProperties: Map, - ) { - - private var hashCode: Int = 0 +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { - /** The dataset to use */ - @JsonProperty("data") fun data(): Data? = data + /** + * The dataset to use + * + * @throws BraintrustInvalidDataException 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 data(): Data = body.data() - /** Unique identifier for the project to run the eval in */ - @JsonProperty("project_id") fun projectId(): String? = projectId + /** + * Unique identifier for the project to run the eval in + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() - /** The functions to score the eval on */ - @JsonProperty("scores") fun scores(): List? = scores + /** + * The functions to score the eval on + * + * @throws BraintrustInvalidDataException 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 scores(): List = body.scores() - /** The function to evaluate */ - @JsonProperty("task") fun task(): Task? = task + /** + * The function to evaluate + * + * @throws BraintrustInvalidDataException 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 task(): Task = body.task() - /** - * An optional name for the experiment created by this eval. If it conflicts with an - * existing experiment, it will be suffixed with a unique identifier. - */ - @JsonProperty("experiment_name") fun experimentName(): String? = experimentName + /** + * An optional experiment id to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baseExperimentId(): Optional = body.baseExperimentId() - /** - * Optional experiment-level metadata to store about the evaluation. You can later use this - * to slice & dice across experiments. - */ - @JsonProperty("metadata") fun metadata(): Metadata? = metadata + /** + * An optional experiment name to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baseExperimentName(): Optional = body.baseExperimentName() - /** - * Whether to stream the results of the eval. If true, the request will return two events: - * one to indicate the experiment has started, and another upon completion. If false, the - * request will return the evaluation's summary upon completion. - */ - @JsonProperty("stream") fun stream(): Boolean? = stream + /** + * An optional name for the experiment created by this eval. If it conflicts with an existing + * experiment, it will be suffixed with a unique identifier. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun experimentName(): Optional = body.experimentName() - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** + * Optional settings for collecting git metadata. By default, will collect all git metadata + * fields allowed in org-level settings. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun gitMetadataSettings(): Optional = body.gitMetadataSettings() - fun toBuilder() = Builder().from(this) + /** + * Whether the experiment should be public. Defaults to false. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun isPublic(): Optional = body.isPublic() - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * The maximum number of tasks/scorers that will be run concurrently. Defaults to undefined, in + * which case there is no max concurrency. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxConcurrency(): Optional = body.maxConcurrency() - return other is EvalCreateBody && - this.data == other.data && - this.projectId == other.projectId && - this.scores == other.scores && - this.task == other.task && - this.experimentName == other.experimentName && - this.metadata == other.metadata && - this.stream == other.stream && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - data, - projectId, - scores, - task, - experimentName, - metadata, - stream, - additionalProperties, - ) - } - return hashCode - } + /** + * Optional experiment-level metadata to store about the evaluation. You can later use this to + * slice & dice across experiments. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() - override fun toString() = - "EvalCreateBody{data=$data, projectId=$projectId, scores=$scores, task=$task, experimentName=$experimentName, metadata=$metadata, stream=$stream, additionalProperties=$additionalProperties}" + /** + * Options for tracing the evaluation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun parent(): Optional = body.parent() - companion object { + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun repoInfo(): Optional = body.repoInfo() - @JvmStatic fun builder() = Builder() - } + /** + * Whether to stream the results of the eval. If true, the request will return two events: one + * to indicate the experiment has started, and another upon completion. If false, the request + * will return the evaluation's summary upon completion. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun stream(): Optional = body.stream() - class Builder { + /** + * The maximum duration, in milliseconds, to run the evaluation. Defaults to undefined, in which + * case there is no timeout. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun timeout(): Optional = body.timeout() - private var data: Data? = null - private var projectId: String? = null - private var scores: List? = null - private var task: Task? = null - private var experimentName: String? = null - private var metadata: Metadata? = null - private var stream: Boolean? = null - private var additionalProperties: MutableMap = mutableMapOf() + /** + * The number of times to run the evaluator per input. This is useful for evaluating + * applications that have non-deterministic behavior and gives you both a stronger aggregate + * measure and a sense of the variance in the results. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun trialCount(): Optional = body.trialCount() - @JvmSynthetic - internal fun from(evalCreateBody: EvalCreateBody) = apply { - this.data = evalCreateBody.data - this.projectId = evalCreateBody.projectId - this.scores = evalCreateBody.scores - this.task = evalCreateBody.task - this.experimentName = evalCreateBody.experimentName - this.metadata = evalCreateBody.metadata - this.stream = evalCreateBody.stream - additionalProperties(evalCreateBody.additionalProperties) - } + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _data(): JsonField = body._data() - /** The dataset to use */ - @JsonProperty("data") fun data(data: Data) = apply { this.data = data } + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() - /** Unique identifier for the project to run the eval in */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _scores(): JsonField> = body._scores() - /** The functions to score the eval on */ - @JsonProperty("scores") fun scores(scores: List) = apply { this.scores = scores } + /** + * Returns the raw JSON value of [task]. + * + * Unlike [task], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _task(): JsonField = body._task() - /** The function to evaluate */ - @JsonProperty("task") fun task(task: Task) = apply { this.task = task } + /** + * Returns the raw JSON value of [baseExperimentId]. + * + * Unlike [baseExperimentId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _baseExperimentId(): JsonField = body._baseExperimentId() - /** - * An optional name for the experiment created by this eval. If it conflicts with an - * existing experiment, it will be suffixed with a unique identifier. - */ - @JsonProperty("experiment_name") - fun experimentName(experimentName: String) = apply { - this.experimentName = experimentName - } + /** + * Returns the raw JSON value of [baseExperimentName]. + * + * Unlike [baseExperimentName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _baseExperimentName(): JsonField = body._baseExperimentName() - /** - * Optional experiment-level metadata to store about the evaluation. You can later use - * this to slice & dice across experiments. - */ - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + /** + * Returns the raw JSON value of [experimentName]. + * + * Unlike [experimentName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _experimentName(): JsonField = body._experimentName() - /** - * Whether to stream the results of the eval. If true, the request will return two - * events: one to indicate the experiment has started, and another upon completion. If - * false, the request will return the evaluation's summary upon completion. - */ - @JsonProperty("stream") fun stream(stream: Boolean) = apply { this.stream = stream } + /** + * Returns the raw JSON value of [gitMetadataSettings]. + * + * Unlike [gitMetadataSettings], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _gitMetadataSettings(): JsonField = body._gitMetadataSettings() - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + /** + * Returns the raw JSON value of [isPublic]. + * + * Unlike [isPublic], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _isPublic(): JsonField = body._isPublic() - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + /** + * Returns the raw JSON value of [maxConcurrency]. + * + * Unlike [maxConcurrency], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxConcurrency(): JsonField = body._maxConcurrency() - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() - fun build(): EvalCreateBody = - EvalCreateBody( - checkNotNull(data) { "`data` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scores) { "`scores` is required but was not set" } - .toUnmodifiable(), - checkNotNull(task) { "`task` is required but was not set" }, - experimentName, - metadata, - stream, - additionalProperties.toUnmodifiable(), - ) - } - } + /** + * Returns the raw JSON value of [parent]. + * + * Unlike [parent], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _parent(): JsonField = body._parent() - fun _additionalQueryParams(): Map> = additionalQueryParams + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _repoInfo(): JsonField = body._repoInfo() - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns the raw JSON value of [stream]. + * + * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _stream(): JsonField = body._stream() - fun _additionalBodyProperties(): Map = additionalBodyProperties + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _timeout(): JsonField = body._timeout() - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Returns the raw JSON value of [trialCount]. + * + * Unlike [trialCount], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _trialCount(): JsonField = body._trialCount() - return other is EvalCreateParams && - this.data == other.data && - this.projectId == other.projectId && - this.scores == other.scores && - this.task == other.task && - this.experimentName == other.experimentName && - this.metadata == other.metadata && - this.stream == other.stream && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + fun _additionalBodyProperties(): Map = body._additionalProperties() - override fun hashCode(): Int { - return Objects.hash( - data, - projectId, - scores, - task, - experimentName, - metadata, - stream, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + fun _additionalHeaders(): Headers = additionalHeaders - override fun toString() = - "EvalCreateParams{data=$data, projectId=$projectId, scores=$scores, task=$task, experimentName=$experimentName, metadata=$metadata, stream=$stream, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + fun _additionalQueryParams(): QueryParams = additionalQueryParams - fun toBuilder() = Builder().from(this) + @JvmSynthetic internal fun _body(): Body = body - companion object { + override fun _headers(): Headers = additionalHeaders - @JvmStatic fun builder() = Builder() - } + override fun _queryParams(): QueryParams = additionalQueryParams @NoAutoDetect - class Builder { - - private var data: Data? = null - private var projectId: String? = null - private var scores: MutableList = mutableListOf() - private var task: Task? = null - private var experimentName: String? = null - private var metadata: Metadata? = null - private var stream: Boolean? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(evalCreateParams: EvalCreateParams) = apply { - this.data = evalCreateParams.data - this.projectId = evalCreateParams.projectId - this.scores(evalCreateParams.scores) - this.task = evalCreateParams.task - this.experimentName = evalCreateParams.experimentName - this.metadata = evalCreateParams.metadata - this.stream = evalCreateParams.stream - additionalQueryParams(evalCreateParams.additionalQueryParams) - additionalHeaders(evalCreateParams.additionalHeaders) - additionalBodyProperties(evalCreateParams.additionalBodyProperties) - } - - /** The dataset to use */ - fun data(data: Data) = apply { this.data = data } - - /** The dataset to use */ - fun data(datasetId: Data.DatasetId) = apply { this.data = Data.ofDatasetId(datasetId) } - - /** The dataset to use */ - fun data(projectDatasetName: Data.ProjectDatasetName) = apply { - this.data = Data.ofProjectDatasetName(projectDatasetName) - } - - /** Unique identifier for the project to run the eval in */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + class Body + @JsonCreator + private constructor( + @JsonProperty("data") @ExcludeMissing private val data: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField> = JsonMissing.of(), + @JsonProperty("task") @ExcludeMissing private val task: JsonField = JsonMissing.of(), + @JsonProperty("base_experiment_id") + @ExcludeMissing + private val baseExperimentId: JsonField = JsonMissing.of(), + @JsonProperty("base_experiment_name") + @ExcludeMissing + private val baseExperimentName: JsonField = JsonMissing.of(), + @JsonProperty("experiment_name") + @ExcludeMissing + private val experimentName: JsonField = JsonMissing.of(), + @JsonProperty("git_metadata_settings") + @ExcludeMissing + private val gitMetadataSettings: JsonField = JsonMissing.of(), + @JsonProperty("is_public") + @ExcludeMissing + private val isPublic: JsonField = JsonMissing.of(), + @JsonProperty("max_concurrency") + @ExcludeMissing + private val maxConcurrency: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("parent") + @ExcludeMissing + private val parent: JsonField = JsonMissing.of(), + @JsonProperty("repo_info") + @ExcludeMissing + private val repoInfo: JsonField = JsonMissing.of(), + @JsonProperty("stream") + @ExcludeMissing + private val stream: JsonField = JsonMissing.of(), + @JsonProperty("timeout") + @ExcludeMissing + private val timeout: JsonField = JsonMissing.of(), + @JsonProperty("trial_count") + @ExcludeMissing + private val trialCount: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { - /** The functions to score the eval on */ - fun scores(scores: List) = apply { - this.scores.clear() - this.scores.addAll(scores) - } + /** + * The dataset to use + * + * @throws BraintrustInvalidDataException 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 data(): Data = data.getRequired("data") - /** The functions to score the eval on */ - fun addScore(score: Score) = apply { this.scores.add(score) } + /** + * Unique identifier for the project to run the eval in + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** The function to evaluate */ - fun task(task: Task) = apply { this.task = task } + /** + * The functions to score the eval on + * + * @throws BraintrustInvalidDataException 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 scores(): List = scores.getRequired("scores") - /** The function to evaluate */ - fun task(functionId: Task.FunctionId) = apply { this.task = Task.ofFunctionId(functionId) } + /** + * The function to evaluate + * + * @throws BraintrustInvalidDataException 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 task(): Task = task.getRequired("task") - /** The function to evaluate */ - fun task(projectSlug: Task.ProjectSlug) = apply { - this.task = Task.ofProjectSlug(projectSlug) - } + /** + * An optional experiment id to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun baseExperimentId(): Optional = + Optional.ofNullable(baseExperimentId.getNullable("base_experiment_id")) - /** The function to evaluate */ - fun task(globalFunction: Task.GlobalFunction) = apply { - this.task = Task.ofGlobalFunction(globalFunction) - } + /** + * An optional experiment name to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun baseExperimentName(): Optional = + Optional.ofNullable(baseExperimentName.getNullable("base_experiment_name")) - /** The function to evaluate */ - fun task(promptSessionId: Task.PromptSessionId) = apply { - this.task = Task.ofPromptSessionId(promptSessionId) - } + /** + * An optional name for the experiment created by this eval. If it conflicts with an + * existing experiment, it will be suffixed with a unique identifier. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun experimentName(): Optional = + Optional.ofNullable(experimentName.getNullable("experiment_name")) - /** The function to evaluate */ - fun task(inlineCode: Task.InlineCode) = apply { this.task = Task.ofInlineCode(inlineCode) } + /** + * Optional settings for collecting git metadata. By default, will collect all git metadata + * fields allowed in org-level settings. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun gitMetadataSettings(): Optional = + Optional.ofNullable(gitMetadataSettings.getNullable("git_metadata_settings")) - /** The function to evaluate */ - fun task(inlinePrompt: Task.InlinePrompt) = apply { - this.task = Task.ofInlinePrompt(inlinePrompt) - } + /** + * Whether the experiment should be public. Defaults to false. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun isPublic(): Optional = Optional.ofNullable(isPublic.getNullable("is_public")) /** - * An optional name for the experiment created by this eval. If it conflicts with an - * existing experiment, it will be suffixed with a unique identifier. + * The maximum number of tasks/scorers that will be run concurrently. Defaults to undefined, + * in which case there is no max concurrency. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun experimentName(experimentName: String) = apply { this.experimentName = experimentName } + fun maxConcurrency(): Optional = + Optional.ofNullable(maxConcurrency.getNullable("max_concurrency")) /** * Optional experiment-level metadata to store about the evaluation. You can later use this * to slice & dice across experiments. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Options for tracing the evaluation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun parent(): Optional = Optional.ofNullable(parent.getNullable("parent")) + + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun repoInfo(): Optional = Optional.ofNullable(repoInfo.getNullable("repo_info")) /** * Whether to stream the results of the eval. If true, the request will return two events: * one to indicate the experiment has started, and another upon completion. If false, the * request will return the evaluation's summary upon completion. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun stream(stream: Boolean) = apply { this.stream = stream } + fun stream(): Optional = Optional.ofNullable(stream.getNullable("stream")) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * The maximum duration, in milliseconds, to run the evaluation. Defaults to undefined, in + * which case there is no timeout. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun timeout(): Optional = Optional.ofNullable(timeout.getNullable("timeout")) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * The number of times to run the evaluator per input. This is useful for evaluating + * applications that have non-deterministic behavior and gives you both a stronger aggregate + * measure and a sense of the variance in the results. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun trialCount(): Optional = + Optional.ofNullable(trialCount.getNullable("trial_count")) - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField> = scores - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** + * Returns the raw JSON value of [task]. + * + * Unlike [task], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("task") @ExcludeMissing fun _task(): JsonField = task - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Returns the raw JSON value of [baseExperimentId]. + * + * Unlike [baseExperimentId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("base_experiment_id") + @ExcludeMissing + fun _baseExperimentId(): JsonField = baseExperimentId - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** + * Returns the raw JSON value of [baseExperimentName]. + * + * Unlike [baseExperimentName], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("base_experiment_name") + @ExcludeMissing + fun _baseExperimentName(): JsonField = baseExperimentName - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } - - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) - } + /** + * Returns the raw JSON value of [experimentName]. + * + * Unlike [experimentName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("experiment_name") + @ExcludeMissing + fun _experimentName(): JsonField = experimentName - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) - } + /** + * Returns the raw JSON value of [gitMetadataSettings]. + * + * Unlike [gitMetadataSettings], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("git_metadata_settings") + @ExcludeMissing + fun _gitMetadataSettings(): JsonField = gitMetadataSettings - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } + /** + * Returns the raw JSON value of [isPublic]. + * + * Unlike [isPublic], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("is_public") @ExcludeMissing fun _isPublic(): JsonField = isPublic - fun build(): EvalCreateParams = - EvalCreateParams( - checkNotNull(data) { "`data` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scores) { "`scores` is required but was not set" }.toUnmodifiable(), - checkNotNull(task) { "`task` is required but was not set" }, - experimentName, - metadata, - stream, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + /** + * Returns the raw JSON value of [maxConcurrency]. + * + * Unlike [maxConcurrency], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_concurrency") + @ExcludeMissing + fun _maxConcurrency(): JsonField = maxConcurrency - @JsonDeserialize(using = Data.Deserializer::class) - @JsonSerialize(using = Data.Serializer::class) - class Data - private constructor( - private val datasetId: DatasetId? = null, - private val projectDatasetName: ProjectDatasetName? = null, - private val _json: JsonValue? = null, - ) { + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata - private var validated: Boolean = false + /** + * Returns the raw JSON value of [parent]. + * + * Unlike [parent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("parent") @ExcludeMissing fun _parent(): JsonField = parent - /** Dataset id */ - fun datasetId(): Optional = Optional.ofNullable(datasetId) - /** Project and dataset name */ - fun projectDatasetName(): Optional = - Optional.ofNullable(projectDatasetName) + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("repo_info") @ExcludeMissing fun _repoInfo(): JsonField = repoInfo - fun isDatasetId(): Boolean = datasetId != null + /** + * Returns the raw JSON value of [stream]. + * + * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream") @ExcludeMissing fun _stream(): JsonField = stream - fun isProjectDatasetName(): Boolean = projectDatasetName != null + /** + * Returns the raw JSON value of [timeout]. + * + * Unlike [timeout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("timeout") @ExcludeMissing fun _timeout(): JsonField = timeout - fun asDatasetId(): DatasetId = datasetId.getOrThrow("datasetId") + /** + * Returns the raw JSON value of [trialCount]. + * + * Unlike [trialCount], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("trial_count") + @ExcludeMissing + fun _trialCount(): JsonField = trialCount - fun asProjectDatasetName(): ProjectDatasetName = - projectDatasetName.getOrThrow("projectDatasetName") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - fun _json(): Optional = Optional.ofNullable(_json) + private var validated: Boolean = false - fun accept(visitor: Visitor): T { - return when { - datasetId != null -> visitor.visitDatasetId(datasetId) - projectDatasetName != null -> visitor.visitProjectDatasetName(projectDatasetName) - else -> visitor.unknown(_json) + fun validate(): Body = apply { + if (validated) { + return@apply } - } - fun validate(): Data = apply { - if (!validated) { - if (datasetId == null && projectDatasetName == null) { - throw BraintrustInvalidDataException("Unknown Data: $_json") - } - datasetId?.validate() - projectDatasetName?.validate() - validated = true - } + data().validate() + projectId() + scores().forEach { it.validate() } + task().validate() + baseExperimentId() + baseExperimentName() + experimentName() + gitMetadataSettings().ifPresent { it.validate() } + isPublic() + maxConcurrency() + metadata().ifPresent { it.validate() } + parent().ifPresent { it.validate() } + repoInfo().ifPresent { it.validate() } + stream() + timeout() + trialCount() + validated = true } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun toBuilder() = Builder().from(this) - return other is Data && - this.datasetId == other.datasetId && - this.projectDatasetName == other.projectDatasetName - } + companion object { - override fun hashCode(): Int { - return Objects.hash(datasetId, projectDatasetName) + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .data() + * .projectId() + * .scores() + * .task() + * ``` + */ + @JvmStatic fun builder() = Builder() } - override fun toString(): String { - return when { - datasetId != null -> "Data{datasetId=$datasetId}" - projectDatasetName != null -> "Data{projectDatasetName=$projectDatasetName}" - _json != null -> "Data{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Data") + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var data: JsonField? = null + private var projectId: JsonField? = null + private var scores: JsonField>? = null + private var task: JsonField? = null + private var baseExperimentId: JsonField = JsonMissing.of() + private var baseExperimentName: JsonField = JsonMissing.of() + private var experimentName: JsonField = JsonMissing.of() + private var gitMetadataSettings: JsonField = JsonMissing.of() + private var isPublic: JsonField = JsonMissing.of() + private var maxConcurrency: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var parent: JsonField = JsonMissing.of() + private var repoInfo: JsonField = JsonMissing.of() + private var stream: JsonField = JsonMissing.of() + private var timeout: JsonField = JsonMissing.of() + private var trialCount: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + data = body.data + projectId = body.projectId + scores = body.scores.map { it.toMutableList() } + task = body.task + baseExperimentId = body.baseExperimentId + baseExperimentName = body.baseExperimentName + experimentName = body.experimentName + gitMetadataSettings = body.gitMetadataSettings + isPublic = body.isPublic + maxConcurrency = body.maxConcurrency + metadata = body.metadata + parent = body.parent + repoInfo = body.repoInfo + stream = body.stream + timeout = body.timeout + trialCount = body.trialCount + additionalProperties = body.additionalProperties.toMutableMap() } - } - companion object { + /** The dataset to use */ + fun data(data: Data) = data(JsonField.of(data)) - @JvmStatic fun ofDatasetId(datasetId: DatasetId) = Data(datasetId = datasetId) + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun data(data: JsonField) = apply { this.data = data } - @JvmStatic - fun ofProjectDatasetName(projectDatasetName: ProjectDatasetName) = - Data(projectDatasetName = projectDatasetName) - } + /** Alias for calling [data] with `Data.ofDatasetId(datasetId)`. */ + fun data(datasetId: Data.DatasetId) = data(Data.ofDatasetId(datasetId)) - interface Visitor { + /** Alias for calling [data] with `Data.ofProjectDatasetName(projectDatasetName)`. */ + fun data(projectDatasetName: Data.ProjectDatasetName) = + data(Data.ofProjectDatasetName(projectDatasetName)) - fun visitDatasetId(datasetId: DatasetId): T + /** Alias for calling [data] with `Data.ofDatasetRows(datasetRows)`. */ + fun data(datasetRows: Data.DatasetRows) = data(Data.ofDatasetRows(datasetRows)) - fun visitProjectDatasetName(projectDatasetName: ProjectDatasetName): T + /** Unique identifier for the project to run the eval in */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Data: $json") - } - } + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - class Deserializer : BaseDeserializer(Data::class) { + /** The functions to score the eval on */ + fun scores(scores: List) = scores(JsonField.of(scores)) - override fun ObjectCodec.deserialize(node: JsonNode): Data { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Data(datasetId = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Data(projectDatasetName = it, _json = json) - } + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scores(scores: JsonField>) = apply { + this.scores = scores.map { it.toMutableList() } + } - return Data(_json = json) + /** + * Adds a single [Score] to [scores]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addScore(score: Score) = apply { + scores = + (scores ?: JsonField.of(mutableListOf())).also { + checkKnown("scores", it).add(score) + } } - } - class Serializer : BaseSerializer(Data::class) { + /** Alias for calling [addScore] with `Score.ofFunctionId(functionId)`. */ + fun addScore(functionId: Score.FunctionId) = addScore(Score.ofFunctionId(functionId)) - override fun serialize( - value: Data, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.datasetId != null -> generator.writeObject(value.datasetId) - value.projectDatasetName != null -> - generator.writeObject(value.projectDatasetName) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Data") - } - } - } + /** Alias for calling [addScore] with `Score.ofProjectSlug(projectSlug)`. */ + fun addScore(projectSlug: Score.ProjectSlug) = + addScore(Score.ofProjectSlug(projectSlug)) - /** Dataset id */ - @JsonDeserialize(builder = DatasetId.Builder::class) - @NoAutoDetect - class DatasetId - private constructor( - private val datasetId: JsonField, - private val additionalProperties: Map, - ) { + /** Alias for calling [addScore] with `Score.ofGlobalFunction(globalFunction)`. */ + fun addScore(globalFunction: Score.GlobalFunction) = + addScore(Score.ofGlobalFunction(globalFunction)) - private var validated: Boolean = false + /** Alias for calling [addScore] with `Score.ofPromptSessionId(promptSessionId)`. */ + fun addScore(promptSessionId: Score.PromptSessionId) = + addScore(Score.ofPromptSessionId(promptSessionId)) - private var hashCode: Int = 0 + /** Alias for calling [addScore] with `Score.ofInlineCode(inlineCode)`. */ + fun addScore(inlineCode: Score.InlineCode) = addScore(Score.ofInlineCode(inlineCode)) - fun datasetId(): String = datasetId.getRequired("dataset_id") + /** Alias for calling [addScore] with `Score.ofInlinePrompt(inlinePrompt)`. */ + fun addScore(inlinePrompt: Score.InlinePrompt) = + addScore(Score.ofInlinePrompt(inlinePrompt)) - @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId() = datasetId + /** The function to evaluate */ + fun task(task: Task) = task(JsonField.of(task)) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** + * Sets [Builder.task] to an arbitrary JSON value. + * + * You should usually call [Builder.task] with a well-typed [Task] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun task(task: JsonField) = apply { this.task = task } - fun validate(): DatasetId = apply { - if (!validated) { - datasetId() - validated = true - } - } + /** Alias for calling [task] with `Task.ofFunctionId(functionId)`. */ + fun task(functionId: Task.FunctionId) = task(Task.ofFunctionId(functionId)) - fun toBuilder() = Builder().from(this) + /** Alias for calling [task] with `Task.ofProjectSlug(projectSlug)`. */ + fun task(projectSlug: Task.ProjectSlug) = task(Task.ofProjectSlug(projectSlug)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Alias for calling [task] with `Task.ofGlobalFunction(globalFunction)`. */ + fun task(globalFunction: Task.GlobalFunction) = + task(Task.ofGlobalFunction(globalFunction)) - return other is DatasetId && - this.datasetId == other.datasetId && - this.additionalProperties == other.additionalProperties - } + /** Alias for calling [task] with `Task.ofPromptSessionId(promptSessionId)`. */ + fun task(promptSessionId: Task.PromptSessionId) = + task(Task.ofPromptSessionId(promptSessionId)) - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(datasetId, additionalProperties) - } - return hashCode - } + /** Alias for calling [task] with `Task.ofInlineCode(inlineCode)`. */ + fun task(inlineCode: Task.InlineCode) = task(Task.ofInlineCode(inlineCode)) - override fun toString() = - "DatasetId{datasetId=$datasetId, additionalProperties=$additionalProperties}" + /** Alias for calling [task] with `Task.ofInlinePrompt(inlinePrompt)`. */ + fun task(inlinePrompt: Task.InlinePrompt) = task(Task.ofInlinePrompt(inlinePrompt)) - companion object { + /** + * An optional experiment id to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + */ + fun baseExperimentId(baseExperimentId: String?) = + baseExperimentId(JsonField.ofNullable(baseExperimentId)) - @JvmStatic fun builder() = Builder() - } + /** + * Alias for calling [Builder.baseExperimentId] with `baseExperimentId.orElse(null)`. + */ + fun baseExperimentId(baseExperimentId: Optional) = + baseExperimentId(baseExperimentId.getOrNull()) - class Builder { + /** + * Sets [Builder.baseExperimentId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExperimentId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExperimentId(baseExperimentId: JsonField) = apply { + this.baseExperimentId = baseExperimentId + } - private var datasetId: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * An optional experiment name to use as a base. If specified, the new experiment will + * be summarized and compared to this experiment. + */ + fun baseExperimentName(baseExperimentName: String?) = + baseExperimentName(JsonField.ofNullable(baseExperimentName)) - @JvmSynthetic - internal fun from(datasetId: DatasetId) = apply { - this.datasetId = datasetId.datasetId - additionalProperties(datasetId.additionalProperties) - } + /** + * Alias for calling [Builder.baseExperimentName] with + * `baseExperimentName.orElse(null)`. + */ + fun baseExperimentName(baseExperimentName: Optional) = + baseExperimentName(baseExperimentName.getOrNull()) - fun datasetId(datasetId: String) = datasetId(JsonField.of(datasetId)) + /** + * Sets [Builder.baseExperimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExperimentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExperimentName(baseExperimentName: JsonField) = apply { + this.baseExperimentName = baseExperimentName + } - @JsonProperty("dataset_id") - @ExcludeMissing - fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } + /** + * An optional name for the experiment created by this eval. If it conflicts with an + * existing experiment, it will be suffixed with a unique identifier. + */ + fun experimentName(experimentName: String) = + experimentName(JsonField.of(experimentName)) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + /** + * Sets [Builder.experimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.experimentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun experimentName(experimentName: JsonField) = apply { + this.experimentName = experimentName + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + /** + * Optional settings for collecting git metadata. By default, will collect all git + * metadata fields allowed in org-level settings. + */ + fun gitMetadataSettings(gitMetadataSettings: GitMetadataSettings?) = + gitMetadataSettings(JsonField.ofNullable(gitMetadataSettings)) - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Alias for calling [Builder.gitMetadataSettings] with + * `gitMetadataSettings.orElse(null)`. + */ + fun gitMetadataSettings(gitMetadataSettings: Optional) = + gitMetadataSettings(gitMetadataSettings.getOrNull()) - fun build(): DatasetId = DatasetId(datasetId, additionalProperties.toUnmodifiable()) + /** + * Sets [Builder.gitMetadataSettings] to an arbitrary JSON value. + * + * You should usually call [Builder.gitMetadataSettings] with a well-typed + * [GitMetadataSettings] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun gitMetadataSettings(gitMetadataSettings: JsonField) = apply { + this.gitMetadataSettings = gitMetadataSettings } - } - - /** Project and dataset name */ - @JsonDeserialize(builder = ProjectDatasetName.Builder::class) - @NoAutoDetect - class ProjectDatasetName - private constructor( - private val projectName: JsonField, - private val datasetName: JsonField, - private val additionalProperties: Map, - ) { - private var validated: Boolean = false + /** Whether the experiment should be public. Defaults to false. */ + fun isPublic(isPublic: Boolean?) = isPublic(JsonField.ofNullable(isPublic)) - private var hashCode: Int = 0 + /** + * Alias for [Builder.isPublic]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isPublic(isPublic: Boolean) = isPublic(isPublic as Boolean?) - fun projectName(): String = projectName.getRequired("project_name") + /** Alias for calling [Builder.isPublic] with `isPublic.orElse(null)`. */ + fun isPublic(isPublic: Optional) = isPublic(isPublic.getOrNull()) - fun datasetName(): String = datasetName.getRequired("dataset_name") + /** + * Sets [Builder.isPublic] to an arbitrary JSON value. + * + * You should usually call [Builder.isPublic] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isPublic(isPublic: JsonField) = apply { this.isPublic = isPublic } - @JsonProperty("project_name") @ExcludeMissing fun _projectName() = projectName + /** + * The maximum number of tasks/scorers that will be run concurrently. Defaults to + * undefined, in which case there is no max concurrency. + */ + fun maxConcurrency(maxConcurrency: Double?) = + maxConcurrency(JsonField.ofNullable(maxConcurrency)) - @JsonProperty("dataset_name") @ExcludeMissing fun _datasetName() = datasetName + /** + * Alias for [Builder.maxConcurrency]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxConcurrency(maxConcurrency: Double) = maxConcurrency(maxConcurrency as Double?) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** Alias for calling [Builder.maxConcurrency] with `maxConcurrency.orElse(null)`. */ + fun maxConcurrency(maxConcurrency: Optional) = + maxConcurrency(maxConcurrency.getOrNull()) - fun validate(): ProjectDatasetName = apply { - if (!validated) { - projectName() - datasetName() - validated = true - } + /** + * Sets [Builder.maxConcurrency] to an arbitrary JSON value. + * + * You should usually call [Builder.maxConcurrency] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxConcurrency(maxConcurrency: JsonField) = apply { + this.maxConcurrency = maxConcurrency } - fun toBuilder() = Builder().from(this) + /** + * Optional experiment-level metadata to store about the evaluation. You can later use + * this to slice & dice across experiments. + */ + fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - return other is ProjectDatasetName && - this.projectName == other.projectName && - this.datasetName == other.datasetName && - this.additionalProperties == other.additionalProperties - } + /** Options for tracing the evaluation */ + fun parent(parent: Parent) = parent(JsonField.of(parent)) - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectName, - datasetName, - additionalProperties, - ) - } - return hashCode + /** + * Sets [Builder.parent] to an arbitrary JSON value. + * + * You should usually call [Builder.parent] with a well-typed [Parent] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun parent(parent: JsonField) = apply { this.parent = parent } + + /** Alias for calling [parent] with `Parent.ofSpanParentStruct(spanParentStruct)`. */ + fun parent(spanParentStruct: Parent.SpanParentStruct) = + parent(Parent.ofSpanParentStruct(spanParentStruct)) + + /** Alias for calling [parent] with `Parent.ofString(string)`. */ + fun parent(string: String) = parent(Parent.ofString(string)) + + /** Metadata about the state of the repo when the experiment was created */ + fun repoInfo(repoInfo: RepoInfo?) = repoInfo(JsonField.ofNullable(repoInfo)) + + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) + + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun repoInfo(repoInfo: JsonField) = apply { this.repoInfo = repoInfo } + + /** + * Whether to stream the results of the eval. If true, the request will return two + * events: one to indicate the experiment has started, and another upon completion. If + * false, the request will return the evaluation's summary upon completion. + */ + fun stream(stream: Boolean) = stream(JsonField.of(stream)) + + /** + * Sets [Builder.stream] to an arbitrary JSON value. + * + * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun stream(stream: JsonField) = apply { this.stream = stream } + + /** + * The maximum duration, in milliseconds, to run the evaluation. Defaults to undefined, + * in which case there is no timeout. + */ + fun timeout(timeout: Double?) = timeout(JsonField.ofNullable(timeout)) + + /** + * Alias for [Builder.timeout]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun timeout(timeout: Double) = timeout(timeout as Double?) + + /** Alias for calling [Builder.timeout] with `timeout.orElse(null)`. */ + fun timeout(timeout: Optional) = timeout(timeout.getOrNull()) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun timeout(timeout: JsonField) = apply { this.timeout = timeout } + + /** + * The number of times to run the evaluator per input. This is useful for evaluating + * applications that have non-deterministic behavior and gives you both a stronger + * aggregate measure and a sense of the variance in the results. + */ + fun trialCount(trialCount: Double?) = trialCount(JsonField.ofNullable(trialCount)) + + /** + * Alias for [Builder.trialCount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun trialCount(trialCount: Double) = trialCount(trialCount as Double?) + + /** Alias for calling [Builder.trialCount] with `trialCount.orElse(null)`. */ + fun trialCount(trialCount: Optional) = trialCount(trialCount.getOrNull()) + + /** + * Sets [Builder.trialCount] to an arbitrary JSON value. + * + * You should usually call [Builder.trialCount] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun trialCount(trialCount: JsonField) = apply { this.trialCount = trialCount } + + 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 + * .data() + * .projectId() + * .scores() + * .task() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("data", data), + checkRequired("projectId", projectId), + checkRequired("scores", scores).map { it.toImmutable() }, + checkRequired("task", task), + baseExperimentId, + baseExperimentName, + experimentName, + gitMetadataSettings, + isPublic, + maxConcurrency, + metadata, + parent, + repoInfo, + stream, + timeout, + trialCount, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && data == other.data && projectId == other.projectId && scores == other.scores && task == other.task && baseExperimentId == other.baseExperimentId && baseExperimentName == other.baseExperimentName && experimentName == other.experimentName && gitMetadataSettings == other.gitMetadataSettings && isPublic == other.isPublic && maxConcurrency == other.maxConcurrency && metadata == other.metadata && parent == other.parent && repoInfo == other.repoInfo && stream == other.stream && timeout == other.timeout && trialCount == other.trialCount && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, projectId, scores, task, baseExperimentId, baseExperimentName, experimentName, gitMetadataSettings, isPublic, maxConcurrency, metadata, parent, repoInfo, stream, timeout, trialCount, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{data=$data, projectId=$projectId, scores=$scores, task=$task, baseExperimentId=$baseExperimentId, baseExperimentName=$baseExperimentName, experimentName=$experimentName, gitMetadataSettings=$gitMetadataSettings, isPublic=$isPublic, maxConcurrency=$maxConcurrency, metadata=$metadata, parent=$parent, repoInfo=$repoInfo, stream=$stream, timeout=$timeout, trialCount=$trialCount, additionalProperties=$additionalProperties}" + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EvalCreateParams]. + * + * The following fields are required: + * ```java + * .data() + * .projectId() + * .scores() + * .task() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EvalCreateParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + 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(evalCreateParams: EvalCreateParams) = apply { + body = evalCreateParams.body.toBuilder() + additionalHeaders = evalCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = evalCreateParams.additionalQueryParams.toBuilder() + } + + /** The dataset to use */ + fun data(data: Data) = apply { body.data(data) } + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { body.data(data) } + + /** Alias for calling [data] with `Data.ofDatasetId(datasetId)`. */ + fun data(datasetId: Data.DatasetId) = apply { body.data(datasetId) } + + /** Alias for calling [data] with `Data.ofProjectDatasetName(projectDatasetName)`. */ + fun data(projectDatasetName: Data.ProjectDatasetName) = apply { + body.data(projectDatasetName) + } + + /** Alias for calling [data] with `Data.ofDatasetRows(datasetRows)`. */ + fun data(datasetRows: Data.DatasetRows) = apply { body.data(datasetRows) } + + /** Unique identifier for the project to run the eval in */ + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } + + /** The functions to score the eval on */ + fun scores(scores: List) = apply { body.scores(scores) } + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun scores(scores: JsonField>) = apply { body.scores(scores) } + + /** + * Adds a single [Score] to [scores]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addScore(score: Score) = apply { body.addScore(score) } + + /** Alias for calling [addScore] with `Score.ofFunctionId(functionId)`. */ + fun addScore(functionId: Score.FunctionId) = apply { body.addScore(functionId) } + + /** Alias for calling [addScore] with `Score.ofProjectSlug(projectSlug)`. */ + fun addScore(projectSlug: Score.ProjectSlug) = apply { body.addScore(projectSlug) } + + /** Alias for calling [addScore] with `Score.ofGlobalFunction(globalFunction)`. */ + fun addScore(globalFunction: Score.GlobalFunction) = apply { body.addScore(globalFunction) } + + /** Alias for calling [addScore] with `Score.ofPromptSessionId(promptSessionId)`. */ + fun addScore(promptSessionId: Score.PromptSessionId) = apply { + body.addScore(promptSessionId) + } + + /** Alias for calling [addScore] with `Score.ofInlineCode(inlineCode)`. */ + fun addScore(inlineCode: Score.InlineCode) = apply { body.addScore(inlineCode) } + + /** Alias for calling [addScore] with `Score.ofInlinePrompt(inlinePrompt)`. */ + fun addScore(inlinePrompt: Score.InlinePrompt) = apply { body.addScore(inlinePrompt) } + + /** The function to evaluate */ + fun task(task: Task) = apply { body.task(task) } + + /** + * Sets [Builder.task] to an arbitrary JSON value. + * + * You should usually call [Builder.task] with a well-typed [Task] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun task(task: JsonField) = apply { body.task(task) } + + /** Alias for calling [task] with `Task.ofFunctionId(functionId)`. */ + fun task(functionId: Task.FunctionId) = apply { body.task(functionId) } + + /** Alias for calling [task] with `Task.ofProjectSlug(projectSlug)`. */ + fun task(projectSlug: Task.ProjectSlug) = apply { body.task(projectSlug) } + + /** Alias for calling [task] with `Task.ofGlobalFunction(globalFunction)`. */ + fun task(globalFunction: Task.GlobalFunction) = apply { body.task(globalFunction) } + + /** Alias for calling [task] with `Task.ofPromptSessionId(promptSessionId)`. */ + fun task(promptSessionId: Task.PromptSessionId) = apply { body.task(promptSessionId) } + + /** Alias for calling [task] with `Task.ofInlineCode(inlineCode)`. */ + fun task(inlineCode: Task.InlineCode) = apply { body.task(inlineCode) } + + /** Alias for calling [task] with `Task.ofInlinePrompt(inlinePrompt)`. */ + fun task(inlinePrompt: Task.InlinePrompt) = apply { body.task(inlinePrompt) } + + /** + * An optional experiment id to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + */ + fun baseExperimentId(baseExperimentId: String?) = apply { + body.baseExperimentId(baseExperimentId) + } + + /** Alias for calling [Builder.baseExperimentId] with `baseExperimentId.orElse(null)`. */ + fun baseExperimentId(baseExperimentId: Optional) = + baseExperimentId(baseExperimentId.getOrNull()) + + /** + * Sets [Builder.baseExperimentId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExperimentId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExperimentId(baseExperimentId: JsonField) = apply { + body.baseExperimentId(baseExperimentId) + } + + /** + * An optional experiment name to use as a base. If specified, the new experiment will be + * summarized and compared to this experiment. + */ + fun baseExperimentName(baseExperimentName: String?) = apply { + body.baseExperimentName(baseExperimentName) + } + + /** + * Alias for calling [Builder.baseExperimentName] with `baseExperimentName.orElse(null)`. + */ + fun baseExperimentName(baseExperimentName: Optional) = + baseExperimentName(baseExperimentName.getOrNull()) + + /** + * Sets [Builder.baseExperimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExperimentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExperimentName(baseExperimentName: JsonField) = apply { + body.baseExperimentName(baseExperimentName) + } + + /** + * An optional name for the experiment created by this eval. If it conflicts with an + * existing experiment, it will be suffixed with a unique identifier. + */ + fun experimentName(experimentName: String) = apply { body.experimentName(experimentName) } + + /** + * Sets [Builder.experimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.experimentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun experimentName(experimentName: JsonField) = apply { + body.experimentName(experimentName) + } + + /** + * Optional settings for collecting git metadata. By default, will collect all git metadata + * fields allowed in org-level settings. + */ + fun gitMetadataSettings(gitMetadataSettings: GitMetadataSettings?) = apply { + body.gitMetadataSettings(gitMetadataSettings) + } + + /** + * Alias for calling [Builder.gitMetadataSettings] with `gitMetadataSettings.orElse(null)`. + */ + fun gitMetadataSettings(gitMetadataSettings: Optional) = + gitMetadataSettings(gitMetadataSettings.getOrNull()) + + /** + * Sets [Builder.gitMetadataSettings] to an arbitrary JSON value. + * + * You should usually call [Builder.gitMetadataSettings] with a well-typed + * [GitMetadataSettings] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun gitMetadataSettings(gitMetadataSettings: JsonField) = apply { + body.gitMetadataSettings(gitMetadataSettings) + } + + /** Whether the experiment should be public. Defaults to false. */ + fun isPublic(isPublic: Boolean?) = apply { body.isPublic(isPublic) } + + /** + * Alias for [Builder.isPublic]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isPublic(isPublic: Boolean) = isPublic(isPublic as Boolean?) + + /** Alias for calling [Builder.isPublic] with `isPublic.orElse(null)`. */ + fun isPublic(isPublic: Optional) = isPublic(isPublic.getOrNull()) + + /** + * Sets [Builder.isPublic] to an arbitrary JSON value. + * + * You should usually call [Builder.isPublic] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun isPublic(isPublic: JsonField) = apply { body.isPublic(isPublic) } + + /** + * The maximum number of tasks/scorers that will be run concurrently. Defaults to undefined, + * in which case there is no max concurrency. + */ + fun maxConcurrency(maxConcurrency: Double?) = apply { body.maxConcurrency(maxConcurrency) } + + /** + * Alias for [Builder.maxConcurrency]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxConcurrency(maxConcurrency: Double) = maxConcurrency(maxConcurrency as Double?) + + /** Alias for calling [Builder.maxConcurrency] with `maxConcurrency.orElse(null)`. */ + fun maxConcurrency(maxConcurrency: Optional) = + maxConcurrency(maxConcurrency.getOrNull()) + + /** + * Sets [Builder.maxConcurrency] to an arbitrary JSON value. + * + * You should usually call [Builder.maxConcurrency] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxConcurrency(maxConcurrency: JsonField) = apply { + body.maxConcurrency(maxConcurrency) + } + + /** + * Optional experiment-level metadata to store about the evaluation. You can later use this + * to slice & dice across experiments. + */ + fun metadata(metadata: Metadata) = apply { body.metadata(metadata) } + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } + + /** Options for tracing the evaluation */ + fun parent(parent: Parent) = apply { body.parent(parent) } + + /** + * Sets [Builder.parent] to an arbitrary JSON value. + * + * You should usually call [Builder.parent] with a well-typed [Parent] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun parent(parent: JsonField) = apply { body.parent(parent) } + + /** Alias for calling [parent] with `Parent.ofSpanParentStruct(spanParentStruct)`. */ + fun parent(spanParentStruct: Parent.SpanParentStruct) = apply { + body.parent(spanParentStruct) + } + + /** Alias for calling [parent] with `Parent.ofString(string)`. */ + fun parent(string: String) = apply { body.parent(string) } + + /** Metadata about the state of the repo when the experiment was created */ + fun repoInfo(repoInfo: RepoInfo?) = apply { body.repoInfo(repoInfo) } + + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) + + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun repoInfo(repoInfo: JsonField) = apply { body.repoInfo(repoInfo) } + + /** + * Whether to stream the results of the eval. If true, the request will return two events: + * one to indicate the experiment has started, and another upon completion. If false, the + * request will return the evaluation's summary upon completion. + */ + fun stream(stream: Boolean) = apply { body.stream(stream) } + + /** + * Sets [Builder.stream] to an arbitrary JSON value. + * + * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun stream(stream: JsonField) = apply { body.stream(stream) } + + /** + * The maximum duration, in milliseconds, to run the evaluation. Defaults to undefined, in + * which case there is no timeout. + */ + fun timeout(timeout: Double?) = apply { body.timeout(timeout) } + + /** + * Alias for [Builder.timeout]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun timeout(timeout: Double) = timeout(timeout as Double?) + + /** Alias for calling [Builder.timeout] with `timeout.orElse(null)`. */ + fun timeout(timeout: Optional) = timeout(timeout.getOrNull()) + + /** + * Sets [Builder.timeout] to an arbitrary JSON value. + * + * You should usually call [Builder.timeout] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun timeout(timeout: JsonField) = apply { body.timeout(timeout) } + + /** + * The number of times to run the evaluator per input. This is useful for evaluating + * applications that have non-deterministic behavior and gives you both a stronger aggregate + * measure and a sense of the variance in the results. + */ + fun trialCount(trialCount: Double?) = apply { body.trialCount(trialCount) } + + /** + * Alias for [Builder.trialCount]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun trialCount(trialCount: Double) = trialCount(trialCount as Double?) + + /** Alias for calling [Builder.trialCount] with `trialCount.orElse(null)`. */ + fun trialCount(trialCount: Optional) = trialCount(trialCount.getOrNull()) + + /** + * Sets [Builder.trialCount] to an arbitrary JSON value. + * + * You should usually call [Builder.trialCount] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun trialCount(trialCount: JsonField) = apply { body.trialCount(trialCount) } + + 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 [EvalCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .projectId() + * .scores() + * .task() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EvalCreateParams = + EvalCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } + + /** The dataset to use */ + @JsonDeserialize(using = Data.Deserializer::class) + @JsonSerialize(using = Data.Serializer::class) + class Data + private constructor( + private val datasetId: DatasetId? = null, + private val projectDatasetName: ProjectDatasetName? = null, + private val datasetRows: DatasetRows? = null, + private val _json: JsonValue? = null, + ) { + + /** Dataset id */ + fun datasetId(): Optional = Optional.ofNullable(datasetId) + + /** Project and dataset name */ + fun projectDatasetName(): Optional = + Optional.ofNullable(projectDatasetName) + + /** Dataset rows */ + fun datasetRows(): Optional = Optional.ofNullable(datasetRows) + + fun isDatasetId(): Boolean = datasetId != null + + fun isProjectDatasetName(): Boolean = projectDatasetName != null + + fun isDatasetRows(): Boolean = datasetRows != null + + /** Dataset id */ + fun asDatasetId(): DatasetId = datasetId.getOrThrow("datasetId") + + /** Project and dataset name */ + fun asProjectDatasetName(): ProjectDatasetName = + projectDatasetName.getOrThrow("projectDatasetName") + + /** Dataset rows */ + fun asDatasetRows(): DatasetRows = datasetRows.getOrThrow("datasetRows") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + datasetId != null -> visitor.visitDatasetId(datasetId) + projectDatasetName != null -> visitor.visitProjectDatasetName(projectDatasetName) + datasetRows != null -> visitor.visitDatasetRows(datasetRows) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): Data = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitDatasetId(datasetId: DatasetId) { + datasetId.validate() + } + + override fun visitProjectDatasetName(projectDatasetName: ProjectDatasetName) { + projectDatasetName.validate() + } + + override fun visitDatasetRows(datasetRows: DatasetRows) { + datasetRows.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Data && datasetId == other.datasetId && projectDatasetName == other.projectDatasetName && datasetRows == other.datasetRows /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(datasetId, projectDatasetName, datasetRows) /* spotless:on */ + + override fun toString(): String = + when { + datasetId != null -> "Data{datasetId=$datasetId}" + projectDatasetName != null -> "Data{projectDatasetName=$projectDatasetName}" + datasetRows != null -> "Data{datasetRows=$datasetRows}" + _json != null -> "Data{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Data") + } + + companion object { + + /** Dataset id */ + @JvmStatic fun ofDatasetId(datasetId: DatasetId) = Data(datasetId = datasetId) + + /** Project and dataset name */ + @JvmStatic + fun ofProjectDatasetName(projectDatasetName: ProjectDatasetName) = + Data(projectDatasetName = projectDatasetName) + + /** Dataset rows */ + @JvmStatic fun ofDatasetRows(datasetRows: DatasetRows) = Data(datasetRows = datasetRows) + } + + /** An interface that defines how to map each variant of [Data] to a value of type [T]. */ + interface Visitor { + + /** Dataset id */ + fun visitDatasetId(datasetId: DatasetId): T + + /** Project and dataset name */ + fun visitProjectDatasetName(projectDatasetName: ProjectDatasetName): T + + /** Dataset rows */ + fun visitDatasetRows(datasetRows: DatasetRows): T + + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Data: $json") + } + } + + internal class Deserializer : BaseDeserializer(Data::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Data { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(datasetId = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(projectDatasetName = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(datasetRows = it, _json = json) + } + + return Data(_json = json) + } + } + + internal class Serializer : BaseSerializer(Data::class) { + + override fun serialize( + value: Data, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.datasetId != null -> generator.writeObject(value.datasetId) + value.projectDatasetName != null -> + generator.writeObject(value.projectDatasetName) + value.datasetRows != null -> generator.writeObject(value.datasetRows) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Data") + } + } + } + + /** Dataset id */ + @NoAutoDetect + class DatasetId + @JsonCreator + private constructor( + @JsonProperty("dataset_id") + @ExcludeMissing + private val datasetId: JsonField = JsonMissing.of(), + @JsonProperty("_internal_btql") + @ExcludeMissing + private val _internalBtql: JsonField<_InternalBtql> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 datasetId(): String = datasetId.getRequired("dataset_id") + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun _internalBtql(): Optional<_InternalBtql> = + Optional.ofNullable(_internalBtql.getNullable("_internal_btql")) + + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("dataset_id") + @ExcludeMissing + fun _datasetId(): JsonField = datasetId + + /** + * Returns the raw JSON value of [_internalBtql]. + * + * Unlike [_internalBtql], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("_internal_btql") + @ExcludeMissing + fun __internalBtql(): JsonField<_InternalBtql> = _internalBtql + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): DatasetId = apply { + if (validated) { + return@apply + } + + datasetId() + _internalBtql().ifPresent { it.validate() } + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [DatasetId]. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DatasetId]. */ + class Builder internal constructor() { + + private var datasetId: JsonField? = null + private var _internalBtql: JsonField<_InternalBtql> = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(datasetId: DatasetId) = apply { + this.datasetId = datasetId.datasetId + _internalBtql = datasetId._internalBtql + additionalProperties = datasetId.additionalProperties.toMutableMap() + } + + fun datasetId(datasetId: String) = datasetId(JsonField.of(datasetId)) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } + + fun _internalBtql(_internalBtql: _InternalBtql?) = + _internalBtql(JsonField.ofNullable(_internalBtql)) + + /** Alias for calling [Builder._internalBtql] with `_internalBtql.orElse(null)`. */ + fun _internalBtql(_internalBtql: Optional<_InternalBtql>) = + _internalBtql(_internalBtql.getOrNull()) + + /** + * Sets [Builder._internalBtql] to an arbitrary JSON value. + * + * You should usually call [Builder._internalBtql] with a well-typed [_InternalBtql] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun _internalBtql(_internalBtql: JsonField<_InternalBtql>) = apply { + this._internalBtql = _internalBtql + } + + 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 [DatasetId]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): DatasetId = + DatasetId( + checkRequired("datasetId", datasetId), + _internalBtql, + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class _InternalBtql + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): _InternalBtql = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [_InternalBtql]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [_InternalBtql]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(_internalBtql: _InternalBtql) = apply { + additionalProperties = _internalBtql.additionalProperties.toMutableMap() + } + + 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 [_InternalBtql]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): _InternalBtql = _InternalBtql(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is _InternalBtql && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "_InternalBtql{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetId && datasetId == other.datasetId && _internalBtql == other._internalBtql && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(datasetId, _internalBtql, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DatasetId{datasetId=$datasetId, _internalBtql=$_internalBtql, additionalProperties=$additionalProperties}" + } + + /** Project and dataset name */ + @NoAutoDetect + class ProjectDatasetName + @JsonCreator + private constructor( + @JsonProperty("dataset_name") + @ExcludeMissing + private val datasetName: JsonField = JsonMissing.of(), + @JsonProperty("project_name") + @ExcludeMissing + private val projectName: JsonField = JsonMissing.of(), + @JsonProperty("_internal_btql") + @ExcludeMissing + private val _internalBtql: JsonField<_InternalBtql> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 datasetName(): String = datasetName.getRequired("dataset_name") + + /** + * @throws BraintrustInvalidDataException 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 projectName(): String = projectName.getRequired("project_name") + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun _internalBtql(): Optional<_InternalBtql> = + Optional.ofNullable(_internalBtql.getNullable("_internal_btql")) + + /** + * Returns the raw JSON value of [datasetName]. + * + * Unlike [datasetName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("dataset_name") + @ExcludeMissing + fun _datasetName(): JsonField = datasetName + + /** + * Returns the raw JSON value of [projectName]. + * + * Unlike [projectName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("project_name") + @ExcludeMissing + fun _projectName(): JsonField = projectName + + /** + * Returns the raw JSON value of [_internalBtql]. + * + * Unlike [_internalBtql], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("_internal_btql") + @ExcludeMissing + fun __internalBtql(): JsonField<_InternalBtql> = _internalBtql + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): ProjectDatasetName = apply { + if (validated) { + return@apply + } + + datasetName() + projectName() + _internalBtql().ifPresent { it.validate() } + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ProjectDatasetName]. + * + * The following fields are required: + * ```java + * .datasetName() + * .projectName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProjectDatasetName]. */ + class Builder internal constructor() { + + private var datasetName: JsonField? = null + private var projectName: JsonField? = null + private var _internalBtql: JsonField<_InternalBtql> = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(projectDatasetName: ProjectDatasetName) = apply { + datasetName = projectDatasetName.datasetName + projectName = projectDatasetName.projectName + _internalBtql = projectDatasetName._internalBtql + additionalProperties = projectDatasetName.additionalProperties.toMutableMap() + } + + fun datasetName(datasetName: String) = datasetName(JsonField.of(datasetName)) + + /** + * Sets [Builder.datasetName] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun datasetName(datasetName: JsonField) = apply { + this.datasetName = datasetName + } + + fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + + /** + * Sets [Builder.projectName] to an arbitrary JSON value. + * + * You should usually call [Builder.projectName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun projectName(projectName: JsonField) = apply { + this.projectName = projectName + } + + fun _internalBtql(_internalBtql: _InternalBtql?) = + _internalBtql(JsonField.ofNullable(_internalBtql)) + + /** Alias for calling [Builder._internalBtql] with `_internalBtql.orElse(null)`. */ + fun _internalBtql(_internalBtql: Optional<_InternalBtql>) = + _internalBtql(_internalBtql.getOrNull()) + + /** + * Sets [Builder._internalBtql] to an arbitrary JSON value. + * + * You should usually call [Builder._internalBtql] with a well-typed [_InternalBtql] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun _internalBtql(_internalBtql: JsonField<_InternalBtql>) = apply { + this._internalBtql = _internalBtql + } + + 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 [ProjectDatasetName]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetName() + * .projectName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProjectDatasetName = + ProjectDatasetName( + checkRequired("datasetName", datasetName), + checkRequired("projectName", projectName), + _internalBtql, + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class _InternalBtql + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): _InternalBtql = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [_InternalBtql]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [_InternalBtql]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(_internalBtql: _InternalBtql) = apply { + additionalProperties = _internalBtql.additionalProperties.toMutableMap() + } + + 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 [_InternalBtql]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): _InternalBtql = _InternalBtql(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is _InternalBtql && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "_InternalBtql{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectDatasetName && datasetName == other.datasetName && projectName == other.projectName && _internalBtql == other._internalBtql && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(datasetName, projectName, _internalBtql, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectDatasetName{datasetName=$datasetName, projectName=$projectName, _internalBtql=$_internalBtql, additionalProperties=$additionalProperties}" + } + + /** Dataset rows */ + @NoAutoDetect + class DatasetRows + @JsonCreator + private constructor( + @JsonProperty("data") + @ExcludeMissing + private val data: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 data(): List = data.getRequired("data") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): DatasetRows = apply { + if (validated) { + return@apply + } + + data() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [DatasetRows]. + * + * The following fields are required: + * ```java + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DatasetRows]. */ + class Builder internal constructor() { + + private var data: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(datasetRows: DatasetRows) = apply { + data = datasetRows.data.map { it.toMutableList() } + additionalProperties = datasetRows.additionalProperties.toMutableMap() + } + + fun data(data: List) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun data(data: JsonField>) = apply { + this.data = data.map { it.toMutableList() } + } + + /** + * Adds a single [JsonValue] to [Builder.data]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addData(data: JsonValue) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } + + 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 [DatasetRows]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): DatasetRows = + DatasetRows( + checkRequired("data", data).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is DatasetRows && data == other.data && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DatasetRows{data=$data, additionalProperties=$additionalProperties}" + } + } + + /** The function to evaluate */ + @JsonDeserialize(using = Score.Deserializer::class) + @JsonSerialize(using = Score.Serializer::class) + class Score + private constructor( + private val functionId: FunctionId? = null, + private val projectSlug: ProjectSlug? = null, + private val globalFunction: GlobalFunction? = null, + private val promptSessionId: PromptSessionId? = null, + private val inlineCode: InlineCode? = null, + private val inlinePrompt: InlinePrompt? = null, + private val _json: JsonValue? = null, + ) { + + /** Function id */ + fun functionId(): Optional = Optional.ofNullable(functionId) + + /** Project name and slug */ + fun projectSlug(): Optional = Optional.ofNullable(projectSlug) + + /** Global function name */ + fun globalFunction(): Optional = Optional.ofNullable(globalFunction) + + /** Prompt session id */ + fun promptSessionId(): Optional = Optional.ofNullable(promptSessionId) + + /** Inline code function */ + fun inlineCode(): Optional = Optional.ofNullable(inlineCode) + + /** Inline prompt definition */ + fun inlinePrompt(): Optional = Optional.ofNullable(inlinePrompt) + + fun isFunctionId(): Boolean = functionId != null + + fun isProjectSlug(): Boolean = projectSlug != null + + fun isGlobalFunction(): Boolean = globalFunction != null + + fun isPromptSessionId(): Boolean = promptSessionId != null + + fun isInlineCode(): Boolean = inlineCode != null + + fun isInlinePrompt(): Boolean = inlinePrompt != null + + /** Function id */ + fun asFunctionId(): FunctionId = functionId.getOrThrow("functionId") + + /** Project name and slug */ + fun asProjectSlug(): ProjectSlug = projectSlug.getOrThrow("projectSlug") + + /** Global function name */ + fun asGlobalFunction(): GlobalFunction = globalFunction.getOrThrow("globalFunction") + + /** Prompt session id */ + fun asPromptSessionId(): PromptSessionId = promptSessionId.getOrThrow("promptSessionId") + + /** Inline code function */ + fun asInlineCode(): InlineCode = inlineCode.getOrThrow("inlineCode") + + /** Inline prompt definition */ + fun asInlinePrompt(): InlinePrompt = inlinePrompt.getOrThrow("inlinePrompt") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + functionId != null -> visitor.visitFunctionId(functionId) + projectSlug != null -> visitor.visitProjectSlug(projectSlug) + globalFunction != null -> visitor.visitGlobalFunction(globalFunction) + promptSessionId != null -> visitor.visitPromptSessionId(promptSessionId) + inlineCode != null -> visitor.visitInlineCode(inlineCode) + inlinePrompt != null -> visitor.visitInlinePrompt(inlinePrompt) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): Score = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitFunctionId(functionId: FunctionId) { + functionId.validate() + } + + override fun visitProjectSlug(projectSlug: ProjectSlug) { + projectSlug.validate() + } + + override fun visitGlobalFunction(globalFunction: GlobalFunction) { + globalFunction.validate() + } + + override fun visitPromptSessionId(promptSessionId: PromptSessionId) { + promptSessionId.validate() + } + + override fun visitInlineCode(inlineCode: InlineCode) { + inlineCode.validate() + } + + override fun visitInlinePrompt(inlinePrompt: InlinePrompt) { + inlinePrompt.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Score && functionId == other.functionId && projectSlug == other.projectSlug && globalFunction == other.globalFunction && promptSessionId == other.promptSessionId && inlineCode == other.inlineCode && inlinePrompt == other.inlinePrompt /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, projectSlug, globalFunction, promptSessionId, inlineCode, inlinePrompt) /* spotless:on */ + + override fun toString(): String = + when { + functionId != null -> "Score{functionId=$functionId}" + projectSlug != null -> "Score{projectSlug=$projectSlug}" + globalFunction != null -> "Score{globalFunction=$globalFunction}" + promptSessionId != null -> "Score{promptSessionId=$promptSessionId}" + inlineCode != null -> "Score{inlineCode=$inlineCode}" + inlinePrompt != null -> "Score{inlinePrompt=$inlinePrompt}" + _json != null -> "Score{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Score") + } + + companion object { + + /** Function id */ + @JvmStatic fun ofFunctionId(functionId: FunctionId) = Score(functionId = functionId) + + /** Project name and slug */ + @JvmStatic + fun ofProjectSlug(projectSlug: ProjectSlug) = Score(projectSlug = projectSlug) + + /** Global function name */ + @JvmStatic + fun ofGlobalFunction(globalFunction: GlobalFunction) = + Score(globalFunction = globalFunction) + + /** Prompt session id */ + @JvmStatic + fun ofPromptSessionId(promptSessionId: PromptSessionId) = + Score(promptSessionId = promptSessionId) + + /** Inline code function */ + @JvmStatic fun ofInlineCode(inlineCode: InlineCode) = Score(inlineCode = inlineCode) + + /** Inline prompt definition */ + @JvmStatic + fun ofInlinePrompt(inlinePrompt: InlinePrompt) = Score(inlinePrompt = inlinePrompt) + } + + /** An interface that defines how to map each variant of [Score] to a value of type [T]. */ + interface Visitor { + + /** Function id */ + fun visitFunctionId(functionId: FunctionId): T + + /** Project name and slug */ + fun visitProjectSlug(projectSlug: ProjectSlug): T + + /** Global function name */ + fun visitGlobalFunction(globalFunction: GlobalFunction): T + + /** Prompt session id */ + fun visitPromptSessionId(promptSessionId: PromptSessionId): T + + /** Inline code function */ + fun visitInlineCode(inlineCode: InlineCode): T + + /** Inline prompt definition */ + fun visitInlinePrompt(inlinePrompt: InlinePrompt): T + + /** + * Maps an unknown variant of [Score] to a value of type [T]. + * + * An instance of [Score] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Score: $json") + } + } + + internal class Deserializer : BaseDeserializer(Score::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Score { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(functionId = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(projectSlug = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(globalFunction = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(promptSessionId = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(inlineCode = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Score(inlinePrompt = it, _json = json) + } + + return Score(_json = json) + } + } + + internal class Serializer : BaseSerializer(Score::class) { + + override fun serialize( + value: Score, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.functionId != null -> generator.writeObject(value.functionId) + value.projectSlug != null -> generator.writeObject(value.projectSlug) + value.globalFunction != null -> generator.writeObject(value.globalFunction) + value.promptSessionId != null -> generator.writeObject(value.promptSessionId) + value.inlineCode != null -> generator.writeObject(value.inlineCode) + value.inlinePrompt != null -> generator.writeObject(value.inlinePrompt) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Score") + } + } + } + + /** Function id */ + @NoAutoDetect + class FunctionId + @JsonCreator + private constructor( + @JsonProperty("function_id") + @ExcludeMissing + private val functionId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The ID of the function + * + * @throws BraintrustInvalidDataException 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 functionId(): String = functionId.getRequired("function_id") + + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [functionId]. + * + * Unlike [functionId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_id") + @ExcludeMissing + fun _functionId(): JsonField = functionId + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): FunctionId = apply { + if (validated) { + return@apply + } + + functionId() + version() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [FunctionId]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FunctionId]. */ + class Builder internal constructor() { + + private var functionId: JsonField? = null + private var version: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(functionId: FunctionId) = apply { + this.functionId = functionId.functionId + version = functionId.version + additionalProperties = functionId.additionalProperties.toMutableMap() + } + + /** The ID of the function */ + fun functionId(functionId: String) = functionId(JsonField.of(functionId)) + + /** + * Sets [Builder.functionId] to an arbitrary JSON value. + * + * You should usually call [Builder.functionId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun functionId(functionId: JsonField) = apply { + this.functionId = functionId + } + + /** The version of the function */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [FunctionId]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FunctionId = + FunctionId( + checkRequired("functionId", functionId), + version, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionId && functionId == other.functionId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(functionId, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionId{functionId=$functionId, version=$version, additionalProperties=$additionalProperties}" + } + + /** Project name and slug */ + @NoAutoDetect + class ProjectSlug + @JsonCreator + private constructor( + @JsonProperty("project_name") + @ExcludeMissing + private val projectName: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The name of the project containing the function + * + * @throws BraintrustInvalidDataException 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 projectName(): String = projectName.getRequired("project_name") + + /** + * The slug of the function + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") + + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [projectName]. + * + * Unlike [projectName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("project_name") + @ExcludeMissing + fun _projectName(): JsonField = projectName + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): ProjectSlug = apply { + if (validated) { + return@apply + } + + projectName() + slug() + version() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ProjectSlug]. + * + * The following fields are required: + * ```java + * .projectName() + * .slug() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ProjectSlug]. */ + class Builder internal constructor() { + + private var projectName: JsonField? = null + private var slug: JsonField? = null + private var version: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(projectSlug: ProjectSlug) = apply { + projectName = projectSlug.projectName + slug = projectSlug.slug + version = projectSlug.version + additionalProperties = projectSlug.additionalProperties.toMutableMap() + } + + /** The name of the project containing the function */ + fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + + /** + * Sets [Builder.projectName] to an arbitrary JSON value. + * + * You should usually call [Builder.projectName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun projectName(projectName: JsonField) = apply { + this.projectName = projectName + } + + /** The slug of the function */ + fun slug(slug: String) = slug(JsonField.of(slug)) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } + + /** The version of the function */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [ProjectSlug]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectName() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProjectSlug = + ProjectSlug( + checkRequired("projectName", projectName), + checkRequired("slug", slug), + version, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectSlug && projectName == other.projectName && slug == other.slug && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(projectName, slug, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectSlug{projectName=$projectName, slug=$slug, version=$version, additionalProperties=$additionalProperties}" + } + + /** Global function name */ + @NoAutoDetect + class GlobalFunction + @JsonCreator + private constructor( + @JsonProperty("global_function") + @ExcludeMissing + private val globalFunction: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The name of the global function. Currently, the global namespace includes the + * functions in autoevals + * + * @throws BraintrustInvalidDataException 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 globalFunction(): String = globalFunction.getRequired("global_function") + + /** + * Returns the raw JSON value of [globalFunction]. + * + * Unlike [globalFunction], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("global_function") + @ExcludeMissing + fun _globalFunction(): JsonField = globalFunction + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): GlobalFunction = apply { + if (validated) { + return@apply + } + + globalFunction() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [GlobalFunction]. + * + * The following fields are required: + * ```java + * .globalFunction() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GlobalFunction]. */ + class Builder internal constructor() { + + private var globalFunction: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(globalFunction: GlobalFunction) = apply { + this.globalFunction = globalFunction.globalFunction + additionalProperties = globalFunction.additionalProperties.toMutableMap() + } + + /** + * The name of the global function. Currently, the global namespace includes the + * functions in autoevals + */ + fun globalFunction(globalFunction: String) = + globalFunction(JsonField.of(globalFunction)) + + /** + * Sets [Builder.globalFunction] to an arbitrary JSON value. + * + * You should usually call [Builder.globalFunction] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun globalFunction(globalFunction: JsonField) = apply { + this.globalFunction = globalFunction + } + + 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 [GlobalFunction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .globalFunction() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): GlobalFunction = + GlobalFunction( + checkRequired("globalFunction", globalFunction), + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GlobalFunction && globalFunction == other.globalFunction && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(globalFunction, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GlobalFunction{globalFunction=$globalFunction, additionalProperties=$additionalProperties}" + } + + /** Prompt session id */ + @NoAutoDetect + class PromptSessionId + @JsonCreator + private constructor( + @JsonProperty("prompt_session_function_id") + @ExcludeMissing + private val promptSessionFunctionId: JsonField = JsonMissing.of(), + @JsonProperty("prompt_session_id") + @ExcludeMissing + private val promptSessionId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The ID of the function in the prompt session + * + * @throws BraintrustInvalidDataException 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 promptSessionFunctionId(): String = + promptSessionFunctionId.getRequired("prompt_session_function_id") + + /** + * The ID of the prompt session + * + * @throws BraintrustInvalidDataException 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 promptSessionId(): String = promptSessionId.getRequired("prompt_session_id") + + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [promptSessionFunctionId]. + * + * Unlike [promptSessionFunctionId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("prompt_session_function_id") + @ExcludeMissing + fun _promptSessionFunctionId(): JsonField = promptSessionFunctionId + + /** + * Returns the raw JSON value of [promptSessionId]. + * + * Unlike [promptSessionId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("prompt_session_id") + @ExcludeMissing + fun _promptSessionId(): JsonField = promptSessionId + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): PromptSessionId = apply { + if (validated) { + return@apply + } + + promptSessionFunctionId() + promptSessionId() + version() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PromptSessionId]. + * + * The following fields are required: + * ```java + * .promptSessionFunctionId() + * .promptSessionId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PromptSessionId]. */ + class Builder internal constructor() { + + private var promptSessionFunctionId: JsonField? = null + private var promptSessionId: JsonField? = null + private var version: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(promptSessionId: PromptSessionId) = apply { + promptSessionFunctionId = promptSessionId.promptSessionFunctionId + this.promptSessionId = promptSessionId.promptSessionId + version = promptSessionId.version + additionalProperties = promptSessionId.additionalProperties.toMutableMap() + } + + /** The ID of the function in the prompt session */ + fun promptSessionFunctionId(promptSessionFunctionId: String) = + promptSessionFunctionId(JsonField.of(promptSessionFunctionId)) + + /** + * Sets [Builder.promptSessionFunctionId] to an arbitrary JSON value. + * + * You should usually call [Builder.promptSessionFunctionId] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun promptSessionFunctionId(promptSessionFunctionId: JsonField) = apply { + this.promptSessionFunctionId = promptSessionFunctionId + } + + /** The ID of the prompt session */ + fun promptSessionId(promptSessionId: String) = + promptSessionId(JsonField.of(promptSessionId)) + + /** + * Sets [Builder.promptSessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.promptSessionId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun promptSessionId(promptSessionId: JsonField) = apply { + this.promptSessionId = promptSessionId + } + + /** The version of the function */ + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [PromptSessionId]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .promptSessionFunctionId() + * .promptSessionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PromptSessionId = + PromptSessionId( + checkRequired("promptSessionFunctionId", promptSessionFunctionId), + checkRequired("promptSessionId", promptSessionId), + version, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptSessionId && promptSessionFunctionId == other.promptSessionFunctionId && promptSessionId == other.promptSessionId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(promptSessionFunctionId, promptSessionId, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PromptSessionId{promptSessionFunctionId=$promptSessionFunctionId, promptSessionId=$promptSessionId, version=$version, additionalProperties=$additionalProperties}" + } + + /** Inline code function */ + @NoAutoDetect + class InlineCode + @JsonCreator + private constructor( + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("inline_context") + @ExcludeMissing + private val inlineContext: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The inline code to execute + * + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + + /** + * @throws BraintrustInvalidDataException 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 inlineContext(): InlineContext = inlineContext.getRequired("inline_context") + + /** + * The name of the inline code function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [inlineContext]. + * + * Unlike [inlineContext], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("inline_context") + @ExcludeMissing + fun _inlineContext(): JsonField = inlineContext + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InlineCode = apply { + if (validated) { + return@apply + } + + code() + inlineContext().validate() + name() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [InlineCode]. + * + * The following fields are required: + * ```java + * .code() + * .inlineContext() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InlineCode]. */ + class Builder internal constructor() { + + private var code: JsonField? = null + private var inlineContext: JsonField? = null + private var name: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inlineCode: InlineCode) = apply { + code = inlineCode.code + inlineContext = inlineCode.inlineContext + name = inlineCode.name + additionalProperties = inlineCode.additionalProperties.toMutableMap() + } + + /** The inline code to execute */ + fun code(code: String) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + fun inlineContext(inlineContext: InlineContext) = + inlineContext(JsonField.of(inlineContext)) + + /** + * Sets [Builder.inlineContext] to an arbitrary JSON value. + * + * You should usually call [Builder.inlineContext] with a well-typed [InlineContext] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun inlineContext(inlineContext: JsonField) = apply { + this.inlineContext = inlineContext + } + + /** The name of the inline code function */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } + + 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 [InlineCode]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .inlineContext() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InlineCode = + InlineCode( + checkRequired("code", code), + checkRequired("inlineContext", inlineContext), + name, + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class InlineContext + @JsonCreator + private constructor( + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") + + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InlineContext = apply { + if (validated) { + return@apply + } + + runtime() + version() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [InlineContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InlineContext]. */ + class Builder internal constructor() { + + private var runtime: JsonField? = null + private var version: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(inlineContext: InlineContext) = apply { + runtime = inlineContext.runtime + version = inlineContext.version + additionalProperties = inlineContext.additionalProperties.toMutableMap() + } + + fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) + + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun runtime(runtime: JsonField) = apply { this.runtime = runtime } + + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun version(version: JsonField) = apply { this.version = version } + + 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 [InlineContext]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InlineContext = + InlineContext( + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), + ) + } + + class Runtime + @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 NODE = of("node") + + @JvmField val PYTHON = of("python") + + @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) + } + + /** An enum containing [Runtime]'s known values. */ + enum class Known { + NODE, + PYTHON, + } + + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Runtime] 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 { + NODE, + PYTHON, + /** + * An enum member indicating that [Runtime] 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) { + NODE -> Value.NODE + PYTHON -> Value.PYTHON + 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 BraintrustInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + NODE -> Known.NODE + PYTHON -> Known.PYTHON + else -> throw BraintrustInvalidDataException("Unknown Runtime: $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 BraintrustInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InlineContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InlineContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InlineCode && code == other.code && inlineContext == other.inlineContext && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, inlineContext, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + override fun toString() = - "ProjectDatasetName{projectName=$projectName, datasetName=$datasetName, additionalProperties=$additionalProperties}" + "InlineCode{code=$code, inlineContext=$inlineContext, name=$name, additionalProperties=$additionalProperties}" + } + + /** Inline prompt definition */ + @NoAutoDetect + class InlinePrompt + @JsonCreator + private constructor( + @JsonProperty("inline_prompt") + @ExcludeMissing + private val inlinePrompt: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun inlinePrompt(): Optional = + Optional.ofNullable(inlinePrompt.getNullable("inline_prompt")) + + /** + * The name of the inline prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Returns the raw JSON value of [inlinePrompt]. + * + * Unlike [inlinePrompt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("inline_prompt") + @ExcludeMissing + fun _inlinePrompt(): JsonField = inlinePrompt + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InlinePrompt = apply { + if (validated) { + return@apply + } + + inlinePrompt().ifPresent { it.validate() } + name() + validated = true + } + + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [InlinePrompt]. + * + * The following fields are required: + * ```java + * .inlinePrompt() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InlinePrompt]. */ + class Builder internal constructor() { - private var projectName: JsonField = JsonMissing.of() - private var datasetName: JsonField = JsonMissing.of() + private var inlinePrompt: JsonField? = null + private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectDatasetName: ProjectDatasetName) = apply { - this.projectName = projectDatasetName.projectName - this.datasetName = projectDatasetName.datasetName - additionalProperties(projectDatasetName.additionalProperties) + internal fun from(inlinePrompt: InlinePrompt) = apply { + this.inlinePrompt = inlinePrompt.inlinePrompt + name = inlinePrompt.name + additionalProperties = inlinePrompt.additionalProperties.toMutableMap() } - fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + /** The prompt, model, and its parameters */ + fun inlinePrompt(inlinePrompt: PromptData?) = + inlinePrompt(JsonField.ofNullable(inlinePrompt)) - @JsonProperty("project_name") - @ExcludeMissing - fun projectName(projectName: JsonField) = apply { - this.projectName = projectName + /** Alias for calling [Builder.inlinePrompt] with `inlinePrompt.orElse(null)`. */ + fun inlinePrompt(inlinePrompt: Optional) = + inlinePrompt(inlinePrompt.getOrNull()) + + /** + * Sets [Builder.inlinePrompt] to an arbitrary JSON value. + * + * You should usually call [Builder.inlinePrompt] with a well-typed [PromptData] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun inlinePrompt(inlinePrompt: JsonField) = apply { + this.inlinePrompt = inlinePrompt } - fun datasetName(datasetName: String) = datasetName(JsonField.of(datasetName)) + /** The name of the inline prompt */ + fun name(name: String?) = name(JsonField.ofNullable(name)) - @JsonProperty("dataset_name") - @ExcludeMissing - fun datasetName(datasetName: JsonField) = apply { - this.datasetName = datasetName - } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -799,19 +4280,57 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectDatasetName = - ProjectDatasetName( - projectName, - datasetName, - additionalProperties.toUnmodifiable(), + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [InlinePrompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inlinePrompt() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InlinePrompt = + InlinePrompt( + checkRequired("inlinePrompt", inlinePrompt), + name, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InlinePrompt && inlinePrompt == other.inlinePrompt && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(inlinePrompt, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InlinePrompt{inlinePrompt=$inlinePrompt, name=$name, additionalProperties=$additionalProperties}" } } - @JsonDeserialize(using = Score.Deserializer::class) - @JsonSerialize(using = Score.Serializer::class) - class Score + /** The function to evaluate */ + @JsonDeserialize(using = Task.Deserializer::class) + @JsonSerialize(using = Task.Serializer::class) + class Task private constructor( private val functionId: FunctionId? = null, private val projectSlug: ProjectSlug? = null, @@ -822,18 +4341,21 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** Function id */ fun functionId(): Optional = Optional.ofNullable(functionId) + /** Project name and slug */ fun projectSlug(): Optional = Optional.ofNullable(projectSlug) + /** Global function name */ fun globalFunction(): Optional = Optional.ofNullable(globalFunction) + /** Prompt session id */ fun promptSessionId(): Optional = Optional.ofNullable(promptSessionId) + /** Inline code function */ fun inlineCode(): Optional = Optional.ofNullable(inlineCode) + /** Inline prompt definition */ fun inlinePrompt(): Optional = Optional.ofNullable(inlinePrompt) @@ -849,16 +4371,22 @@ constructor( fun isInlinePrompt(): Boolean = inlinePrompt != null + /** Function id */ fun asFunctionId(): FunctionId = functionId.getOrThrow("functionId") + /** Project name and slug */ fun asProjectSlug(): ProjectSlug = projectSlug.getOrThrow("projectSlug") + /** Global function name */ fun asGlobalFunction(): GlobalFunction = globalFunction.getOrThrow("globalFunction") + /** Prompt session id */ fun asPromptSessionId(): PromptSessionId = promptSessionId.getOrThrow("promptSessionId") + /** Inline code function */ fun asInlineCode(): InlineCode = inlineCode.getOrThrow("inlineCode") + /** Inline prompt definition */ fun asInlinePrompt(): InlinePrompt = inlinePrompt.getOrThrow("inlinePrompt") fun _json(): Optional = Optional.ofNullable(_json) @@ -875,26 +4403,41 @@ constructor( } } - fun validate(): Score = apply { - if (!validated) { - if ( - functionId == null && - projectSlug == null && - globalFunction == null && - promptSessionId == null && - inlineCode == null && - inlinePrompt == null - ) { - throw BraintrustInvalidDataException("Unknown Score: $_json") - } - functionId?.validate() - projectSlug?.validate() - globalFunction?.validate() - promptSessionId?.validate() - inlineCode?.validate() - inlinePrompt?.validate() - validated = true + private var validated: Boolean = false + + fun validate(): Task = apply { + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitFunctionId(functionId: FunctionId) { + functionId.validate() + } + + override fun visitProjectSlug(projectSlug: ProjectSlug) { + projectSlug.validate() + } + + override fun visitGlobalFunction(globalFunction: GlobalFunction) { + globalFunction.validate() + } + + override fun visitPromptSessionId(promptSessionId: PromptSessionId) { + promptSessionId.validate() + } + + override fun visitInlineCode(inlineCode: InlineCode) { + inlineCode.validate() + } + + override fun visitInlinePrompt(inlinePrompt: InlinePrompt) { + inlinePrompt.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -902,118 +4445,124 @@ constructor( return true } - return other is Score && - this.functionId == other.functionId && - this.projectSlug == other.projectSlug && - this.globalFunction == other.globalFunction && - this.promptSessionId == other.promptSessionId && - this.inlineCode == other.inlineCode && - this.inlinePrompt == other.inlinePrompt + return /* spotless:off */ other is Task && functionId == other.functionId && projectSlug == other.projectSlug && globalFunction == other.globalFunction && promptSessionId == other.promptSessionId && inlineCode == other.inlineCode && inlinePrompt == other.inlinePrompt /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - functionId, - projectSlug, - globalFunction, - promptSessionId, - inlineCode, - inlinePrompt, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, projectSlug, globalFunction, promptSessionId, inlineCode, inlinePrompt) /* spotless:on */ - override fun toString(): String { - return when { - functionId != null -> "Score{functionId=$functionId}" - projectSlug != null -> "Score{projectSlug=$projectSlug}" - globalFunction != null -> "Score{globalFunction=$globalFunction}" - promptSessionId != null -> "Score{promptSessionId=$promptSessionId}" - inlineCode != null -> "Score{inlineCode=$inlineCode}" - inlinePrompt != null -> "Score{inlinePrompt=$inlinePrompt}" - _json != null -> "Score{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Score") + override fun toString(): String = + when { + functionId != null -> "Task{functionId=$functionId}" + projectSlug != null -> "Task{projectSlug=$projectSlug}" + globalFunction != null -> "Task{globalFunction=$globalFunction}" + promptSessionId != null -> "Task{promptSessionId=$promptSessionId}" + inlineCode != null -> "Task{inlineCode=$inlineCode}" + inlinePrompt != null -> "Task{inlinePrompt=$inlinePrompt}" + _json != null -> "Task{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Task") } - } companion object { - @JvmStatic fun ofFunctionId(functionId: FunctionId) = Score(functionId = functionId) + /** Function id */ + @JvmStatic fun ofFunctionId(functionId: FunctionId) = Task(functionId = functionId) - @JvmStatic - fun ofProjectSlug(projectSlug: ProjectSlug) = Score(projectSlug = projectSlug) + /** Project name and slug */ + @JvmStatic fun ofProjectSlug(projectSlug: ProjectSlug) = Task(projectSlug = projectSlug) + /** Global function name */ @JvmStatic fun ofGlobalFunction(globalFunction: GlobalFunction) = - Score(globalFunction = globalFunction) + Task(globalFunction = globalFunction) + /** Prompt session id */ @JvmStatic fun ofPromptSessionId(promptSessionId: PromptSessionId) = - Score(promptSessionId = promptSessionId) + Task(promptSessionId = promptSessionId) - @JvmStatic fun ofInlineCode(inlineCode: InlineCode) = Score(inlineCode = inlineCode) + /** Inline code function */ + @JvmStatic fun ofInlineCode(inlineCode: InlineCode) = Task(inlineCode = inlineCode) + /** Inline prompt definition */ @JvmStatic - fun ofInlinePrompt(inlinePrompt: InlinePrompt) = Score(inlinePrompt = inlinePrompt) + fun ofInlinePrompt(inlinePrompt: InlinePrompt) = Task(inlinePrompt = inlinePrompt) } + /** An interface that defines how to map each variant of [Task] to a value of type [T]. */ interface Visitor { + /** Function id */ fun visitFunctionId(functionId: FunctionId): T + /** Project name and slug */ fun visitProjectSlug(projectSlug: ProjectSlug): T + /** Global function name */ fun visitGlobalFunction(globalFunction: GlobalFunction): T + /** Prompt session id */ fun visitPromptSessionId(promptSessionId: PromptSessionId): T + /** Inline code function */ fun visitInlineCode(inlineCode: InlineCode): T + /** Inline prompt definition */ fun visitInlinePrompt(inlinePrompt: InlinePrompt): T + /** + * Maps an unknown variant of [Task] to a value of type [T]. + * + * An instance of [Task] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Score: $json") + throw BraintrustInvalidDataException("Unknown Task: $json") } } - class Deserializer : BaseDeserializer(Score::class) { + internal class Deserializer : BaseDeserializer(Task::class) { - override fun ObjectCodec.deserialize(node: JsonNode): Score { + override fun ObjectCodec.deserialize(node: JsonNode): Task { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(functionId = it, _json = json) + return Task(functionId = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(projectSlug = it, _json = json) + return Task(projectSlug = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(globalFunction = it, _json = json) + return Task(globalFunction = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(promptSessionId = it, _json = json) + return Task(promptSessionId = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(inlineCode = it, _json = json) + return Task(inlineCode = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return Score(inlinePrompt = it, _json = json) + return Task(inlinePrompt = it, _json = json) } - return Score(_json = json) + return Task(_json = json) } } - class Serializer : BaseSerializer(Score::class) { + internal class Serializer : BaseSerializer(Task::class) { override fun serialize( - value: Score, + value: Task, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.functionId != null -> generator.writeObject(value.functionId) @@ -1023,101 +4572,115 @@ constructor( value.inlineCode != null -> generator.writeObject(value.inlineCode) value.inlinePrompt != null -> generator.writeObject(value.inlinePrompt) value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Score") + else -> throw IllegalStateException("Invalid Task") } } } /** Function id */ - @JsonDeserialize(builder = FunctionId.Builder::class) @NoAutoDetect class FunctionId + @JsonCreator private constructor( - private val functionId: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("function_id") + @ExcludeMissing + private val functionId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The ID of the function */ + /** + * The ID of the function + * + * @throws BraintrustInvalidDataException 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 functionId(): String = functionId.getRequired("function_id") - /** The version of the function */ + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun version(): Optional = Optional.ofNullable(version.getNullable("version")) - /** The ID of the function */ - @JsonProperty("function_id") @ExcludeMissing fun _functionId() = functionId + /** + * Returns the raw JSON value of [functionId]. + * + * Unlike [functionId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_id") + @ExcludeMissing + fun _functionId(): JsonField = functionId - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FunctionId = apply { - if (!validated) { - functionId() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionId = apply { + if (validated) { + return@apply } - return other is FunctionId && - this.functionId == other.functionId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - functionId, - version, - additionalProperties, - ) - } - return hashCode + functionId() + version() + validated = true } - override fun toString() = - "FunctionId{functionId=$functionId, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionId]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionId]. */ + class Builder internal constructor() { - private var functionId: JsonField = JsonMissing.of() + private var functionId: JsonField? = null private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionId: FunctionId) = apply { this.functionId = functionId.functionId - this.version = functionId.version - additionalProperties(functionId.additionalProperties) + version = functionId.version + additionalProperties = functionId.additionalProperties.toMutableMap() } /** The ID of the function */ fun functionId(functionId: String) = functionId(JsonField.of(functionId)) - /** The ID of the function */ - @JsonProperty("function_id") - @ExcludeMissing + /** + * Sets [Builder.functionId] to an arbitrary JSON value. + * + * You should usually call [Builder.functionId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun functionId(functionId: JsonField) = apply { this.functionId = functionId } @@ -1125,19 +4688,22 @@ constructor( /** The version of the function */ fun version(version: String) = version(JsonField.of(version)) - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1145,117 +4711,179 @@ constructor( 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 [FunctionId]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionId = FunctionId( - functionId, + checkRequired("functionId", functionId), version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionId && functionId == other.functionId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(functionId, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionId{functionId=$functionId, version=$version, additionalProperties=$additionalProperties}" } /** Project name and slug */ - @JsonDeserialize(builder = ProjectSlug.Builder::class) @NoAutoDetect class ProjectSlug + @JsonCreator private constructor( - private val projectName: JsonField, - private val slug: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("project_name") + @ExcludeMissing + private val projectName: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The name of the project containing the function */ + /** + * The name of the project containing the function + * + * @throws BraintrustInvalidDataException 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 projectName(): String = projectName.getRequired("project_name") - /** The slug of the function */ + /** + * The slug of the function + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") - /** The version of the function */ + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun version(): Optional = Optional.ofNullable(version.getNullable("version")) - /** The name of the project containing the function */ - @JsonProperty("project_name") @ExcludeMissing fun _projectName() = projectName + /** + * Returns the raw JSON value of [projectName]. + * + * Unlike [projectName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("project_name") + @ExcludeMissing + fun _projectName(): JsonField = projectName - /** The slug of the function */ - @JsonProperty("slug") @ExcludeMissing fun _slug() = slug + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectSlug = apply { - if (!validated) { - projectName() - slug() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectSlug = apply { + if (validated) { + return@apply } - return other is ProjectSlug && - this.projectName == other.projectName && - this.slug == other.slug && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectName, - slug, - version, - additionalProperties, - ) - } - return hashCode + projectName() + slug() + version() + validated = true } - override fun toString() = - "ProjectSlug{projectName=$projectName, slug=$slug, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectSlug]. + * + * The following fields are required: + * ```java + * .projectName() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectSlug]. */ + class Builder internal constructor() { - private var projectName: JsonField = JsonMissing.of() - private var slug: JsonField = JsonMissing.of() + private var projectName: JsonField? = null + private var slug: JsonField? = null private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectSlug: ProjectSlug) = apply { - this.projectName = projectSlug.projectName - this.slug = projectSlug.slug - this.version = projectSlug.version - additionalProperties(projectSlug.additionalProperties) + projectName = projectSlug.projectName + slug = projectSlug.slug + version = projectSlug.version + additionalProperties = projectSlug.additionalProperties.toMutableMap() } /** The name of the project containing the function */ fun projectName(projectName: String) = projectName(JsonField.of(projectName)) - /** The name of the project containing the function */ - @JsonProperty("project_name") - @ExcludeMissing + /** + * Sets [Builder.projectName] to an arbitrary JSON value. + * + * You should usually call [Builder.projectName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun projectName(projectName: JsonField) = apply { this.projectName = projectName } @@ -1263,27 +4891,34 @@ constructor( /** The slug of the function */ fun slug(slug: String) = slug(JsonField.of(slug)) - /** The slug of the function */ - @JsonProperty("slug") - @ExcludeMissing + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun slug(slug: JsonField) = apply { this.slug = slug } /** The version of the function */ fun version(version: String) = version(JsonField.of(version)) - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1291,88 +4926,126 @@ constructor( 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 [ProjectSlug]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectName() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectSlug = ProjectSlug( - projectName, - slug, + checkRequired("projectName", projectName), + checkRequired("slug", slug), version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectSlug && projectName == other.projectName && slug == other.slug && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(projectName, slug, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectSlug{projectName=$projectName, slug=$slug, version=$version, additionalProperties=$additionalProperties}" } /** Global function name */ - @JsonDeserialize(builder = GlobalFunction.Builder::class) @NoAutoDetect class GlobalFunction + @JsonCreator private constructor( - private val globalFunction: JsonField, - private val additionalProperties: Map, + @JsonProperty("global_function") + @ExcludeMissing + private val globalFunction: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * The name of the global function. Currently, the global namespace includes the * functions in autoevals + * + * @throws BraintrustInvalidDataException 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 globalFunction(): String = globalFunction.getRequired("global_function") /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals + * Returns the raw JSON value of [globalFunction]. + * + * Unlike [globalFunction], this method doesn't throw if the JSON field has an + * unexpected type. */ - @JsonProperty("global_function") @ExcludeMissing fun _globalFunction() = globalFunction + @JsonProperty("global_function") + @ExcludeMissing + fun _globalFunction(): JsonField = globalFunction @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): GlobalFunction = apply { - if (!validated) { - globalFunction() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): GlobalFunction = apply { + if (validated) { + return@apply } - return other is GlobalFunction && - this.globalFunction == other.globalFunction && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(globalFunction, additionalProperties) - } - return hashCode + globalFunction() + validated = true } - override fun toString() = - "GlobalFunction{globalFunction=$globalFunction, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GlobalFunction]. + * + * The following fields are required: + * ```java + * .globalFunction() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [GlobalFunction]. */ + class Builder internal constructor() { - private var globalFunction: JsonField = JsonMissing.of() + private var globalFunction: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(globalFunction: GlobalFunction) = apply { this.globalFunction = globalFunction.globalFunction - additionalProperties(globalFunction.additionalProperties) + additionalProperties = globalFunction.additionalProperties.toMutableMap() } /** @@ -1383,23 +5056,23 @@ constructor( globalFunction(JsonField.of(globalFunction)) /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals + * Sets [Builder.globalFunction] to an arbitrary JSON value. + * + * You should usually call [Builder.globalFunction] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - @JsonProperty("global_function") - @ExcludeMissing fun globalFunction(globalFunction: JsonField) = apply { this.globalFunction = globalFunction } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1407,150 +5080,221 @@ constructor( 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 [GlobalFunction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .globalFunction() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): GlobalFunction = - GlobalFunction(globalFunction, additionalProperties.toUnmodifiable()) + GlobalFunction( + checkRequired("globalFunction", globalFunction), + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GlobalFunction && globalFunction == other.globalFunction && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(globalFunction, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GlobalFunction{globalFunction=$globalFunction, additionalProperties=$additionalProperties}" } /** Prompt session id */ - @JsonDeserialize(builder = PromptSessionId.Builder::class) @NoAutoDetect class PromptSessionId + @JsonCreator private constructor( - private val promptSessionId: JsonField, - private val promptSessionFunctionId: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("prompt_session_function_id") + @ExcludeMissing + private val promptSessionFunctionId: JsonField = JsonMissing.of(), + @JsonProperty("prompt_session_id") + @ExcludeMissing + private val promptSessionId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The ID of the prompt session */ - fun promptSessionId(): String = promptSessionId.getRequired("prompt_session_id") - - /** The ID of the function in the prompt session */ + /** + * The ID of the function in the prompt session + * + * @throws BraintrustInvalidDataException 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 promptSessionFunctionId(): String = promptSessionFunctionId.getRequired("prompt_session_function_id") - /** The version of the function */ + /** + * The ID of the prompt session + * + * @throws BraintrustInvalidDataException 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 promptSessionId(): String = promptSessionId.getRequired("prompt_session_id") + + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun version(): Optional = Optional.ofNullable(version.getNullable("version")) - /** The ID of the prompt session */ - @JsonProperty("prompt_session_id") + /** + * Returns the raw JSON value of [promptSessionFunctionId]. + * + * Unlike [promptSessionFunctionId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("prompt_session_function_id") @ExcludeMissing - fun _promptSessionId() = promptSessionId + fun _promptSessionFunctionId(): JsonField = promptSessionFunctionId - /** The ID of the function in the prompt session */ - @JsonProperty("prompt_session_function_id") + /** + * Returns the raw JSON value of [promptSessionId]. + * + * Unlike [promptSessionId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("prompt_session_id") @ExcludeMissing - fun _promptSessionFunctionId() = promptSessionFunctionId + fun _promptSessionId(): JsonField = promptSessionId - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): PromptSessionId = apply { - if (!validated) { - promptSessionId() - promptSessionFunctionId() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): PromptSessionId = apply { + if (validated) { + return@apply } - return other is PromptSessionId && - this.promptSessionId == other.promptSessionId && - this.promptSessionFunctionId == other.promptSessionFunctionId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - promptSessionId, - promptSessionFunctionId, - version, - additionalProperties, - ) - } - return hashCode + promptSessionFunctionId() + promptSessionId() + version() + validated = true } - override fun toString() = - "PromptSessionId{promptSessionId=$promptSessionId, promptSessionFunctionId=$promptSessionFunctionId, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptSessionId]. + * + * The following fields are required: + * ```java + * .promptSessionFunctionId() + * .promptSessionId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [PromptSessionId]. */ + class Builder internal constructor() { - private var promptSessionId: JsonField = JsonMissing.of() - private var promptSessionFunctionId: JsonField = JsonMissing.of() + private var promptSessionFunctionId: JsonField? = null + private var promptSessionId: JsonField? = null private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(promptSessionId: PromptSessionId) = apply { + promptSessionFunctionId = promptSessionId.promptSessionFunctionId this.promptSessionId = promptSessionId.promptSessionId - this.promptSessionFunctionId = promptSessionId.promptSessionFunctionId - this.version = promptSessionId.version - additionalProperties(promptSessionId.additionalProperties) - } - - /** The ID of the prompt session */ - fun promptSessionId(promptSessionId: String) = - promptSessionId(JsonField.of(promptSessionId)) - - /** The ID of the prompt session */ - @JsonProperty("prompt_session_id") - @ExcludeMissing - fun promptSessionId(promptSessionId: JsonField) = apply { - this.promptSessionId = promptSessionId + version = promptSessionId.version + additionalProperties = promptSessionId.additionalProperties.toMutableMap() } /** The ID of the function in the prompt session */ fun promptSessionFunctionId(promptSessionFunctionId: String) = promptSessionFunctionId(JsonField.of(promptSessionFunctionId)) - /** The ID of the function in the prompt session */ - @JsonProperty("prompt_session_function_id") - @ExcludeMissing + /** + * Sets [Builder.promptSessionFunctionId] to an arbitrary JSON value. + * + * You should usually call [Builder.promptSessionFunctionId] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun promptSessionFunctionId(promptSessionFunctionId: JsonField) = apply { this.promptSessionFunctionId = promptSessionFunctionId } + /** The ID of the prompt session */ + fun promptSessionId(promptSessionId: String) = + promptSessionId(JsonField.of(promptSessionId)) + + /** + * Sets [Builder.promptSessionId] to an arbitrary JSON value. + * + * You should usually call [Builder.promptSessionId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun promptSessionId(promptSessionId: JsonField) = apply { + this.promptSessionId = promptSessionId + } + /** The version of the function */ fun version(version: String) = version(JsonField.of(version)) - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1558,143 +5302,217 @@ constructor( 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 [PromptSessionId]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .promptSessionFunctionId() + * .promptSessionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): PromptSessionId = PromptSessionId( - promptSessionId, - promptSessionFunctionId, + checkRequired("promptSessionFunctionId", promptSessionFunctionId), + checkRequired("promptSessionId", promptSessionId), version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptSessionId && promptSessionFunctionId == other.promptSessionFunctionId && promptSessionId == other.promptSessionId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(promptSessionFunctionId, promptSessionId, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PromptSessionId{promptSessionFunctionId=$promptSessionFunctionId, promptSessionId=$promptSessionId, version=$version, additionalProperties=$additionalProperties}" } /** Inline code function */ - @JsonDeserialize(builder = InlineCode.Builder::class) @NoAutoDetect class InlineCode + @JsonCreator private constructor( - private val inlineContext: JsonField, - private val code: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("inline_context") + @ExcludeMissing + private val inlineContext: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * The inline code to execute + * + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + /** + * @throws BraintrustInvalidDataException 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 inlineContext(): InlineContext = inlineContext.getRequired("inline_context") - /** The inline code to execute */ - fun code(): String = code.getRequired("code") - - /** The name of the inline code function */ + /** + * The name of the inline code function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - @JsonProperty("inline_context") @ExcludeMissing fun _inlineContext() = inlineContext + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code - /** The inline code to execute */ - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [inlineContext]. + * + * Unlike [inlineContext], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("inline_context") + @ExcludeMissing + fun _inlineContext(): JsonField = inlineContext - /** The name of the inline code function */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): InlineCode = apply { - if (!validated) { - inlineContext().validate() - code() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): InlineCode = apply { + if (validated) { + return@apply } - return other is InlineCode && - this.inlineContext == other.inlineContext && - this.code == other.code && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - inlineContext, - code, - name, - additionalProperties, - ) - } - return hashCode + code() + inlineContext().validate() + name() + validated = true } - override fun toString() = - "InlineCode{inlineContext=$inlineContext, code=$code, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [InlineCode]. + * + * The following fields are required: + * ```java + * .code() + * .inlineContext() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InlineCode]. */ + class Builder internal constructor() { - private var inlineContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() + private var code: JsonField? = null + private var inlineContext: JsonField? = null private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inlineCode: InlineCode) = apply { - this.inlineContext = inlineCode.inlineContext - this.code = inlineCode.code - this.name = inlineCode.name - additionalProperties(inlineCode.additionalProperties) + code = inlineCode.code + inlineContext = inlineCode.inlineContext + name = inlineCode.name + additionalProperties = inlineCode.additionalProperties.toMutableMap() } + /** The inline code to execute */ + fun code(code: String) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + fun inlineContext(inlineContext: InlineContext) = inlineContext(JsonField.of(inlineContext)) - @JsonProperty("inline_context") - @ExcludeMissing + /** + * Sets [Builder.inlineContext] to an arbitrary JSON value. + * + * You should usually call [Builder.inlineContext] with a well-typed [InlineContext] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ fun inlineContext(inlineContext: JsonField) = apply { this.inlineContext = inlineContext } - /** The inline code to execute */ - fun code(code: String) = code(JsonField.of(code)) - - /** The inline code to execute */ - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } - /** The name of the inline code function */ - fun name(name: String) = name(JsonField.of(name)) + fun name(name: String?) = name(JsonField.ofNullable(name)) - /** The name of the inline code function */ - @JsonProperty("name") - @ExcludeMissing + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1702,114 +5520,157 @@ constructor( 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 [InlineCode]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .inlineContext() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): InlineCode = InlineCode( - inlineContext, - code, + checkRequired("code", code), + checkRequired("inlineContext", inlineContext), name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = InlineContext.Builder::class) @NoAutoDetect class InlineContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): InlineContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): InlineContext = apply { + if (validated) { + return@apply } - return other is InlineContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "InlineContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [InlineContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InlineContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inlineContext: InlineContext) = apply { - this.runtime = inlineContext.runtime - this.version = inlineContext.version - additionalProperties(inlineContext.additionalProperties) + runtime = inlineContext.runtime + version = inlineContext.version + additionalProperties = inlineContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1817,55 +5678,91 @@ constructor( 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 [InlineContext]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): InlineContext = InlineContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } class Runtime @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -1873,6 +5770,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a + * not a known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -1880,123 +5786,204 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown Runtime: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InlineContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InlineContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is InlineCode && code == other.code && inlineContext == other.inlineContext && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, inlineContext, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InlineCode{code=$code, inlineContext=$inlineContext, name=$name, additionalProperties=$additionalProperties}" } /** Inline prompt definition */ - @JsonDeserialize(builder = InlinePrompt.Builder::class) @NoAutoDetect class InlinePrompt + @JsonCreator private constructor( - private val inlinePrompt: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("inline_prompt") + @ExcludeMissing + private val inlinePrompt: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The prompt, model, and its parameters */ + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun inlinePrompt(): Optional = Optional.ofNullable(inlinePrompt.getNullable("inline_prompt")) - /** The name of the inline prompt */ + /** + * The name of the inline prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - /** The prompt, model, and its parameters */ - @JsonProperty("inline_prompt") @ExcludeMissing fun _inlinePrompt() = inlinePrompt - - /** The name of the inline prompt */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonAnyGetter + /** + * Returns the raw JSON value of [inlinePrompt]. + * + * Unlike [inlinePrompt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("inline_prompt") @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InlinePrompt = apply { - if (!validated) { - inlinePrompt().map { it.validate() } - name() - validated = true - } - } + fun _inlinePrompt(): JsonField = inlinePrompt - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * 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 - return other is InlinePrompt && - this.inlinePrompt == other.inlinePrompt && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - inlinePrompt, - name, - additionalProperties, - ) + private var validated: Boolean = false + + fun validate(): InlinePrompt = apply { + if (validated) { + return@apply } - return hashCode + + inlinePrompt().ifPresent { it.validate() } + name() + validated = true } - override fun toString() = - "InlinePrompt{inlinePrompt=$inlinePrompt, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [InlinePrompt]. + * + * The following fields are required: + * ```java + * .inlinePrompt() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InlinePrompt]. */ + class Builder internal constructor() { - private var inlinePrompt: JsonField = JsonMissing.of() + private var inlinePrompt: JsonField? = null private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inlinePrompt: InlinePrompt) = apply { this.inlinePrompt = inlinePrompt.inlinePrompt - this.name = inlinePrompt.name - additionalProperties(inlinePrompt.additionalProperties) + name = inlinePrompt.name + additionalProperties = inlinePrompt.additionalProperties.toMutableMap() } /** The prompt, model, and its parameters */ - fun inlinePrompt(inlinePrompt: PromptData) = - inlinePrompt(JsonField.of(inlinePrompt)) + fun inlinePrompt(inlinePrompt: PromptData?) = + inlinePrompt(JsonField.ofNullable(inlinePrompt)) - /** The prompt, model, and its parameters */ - @JsonProperty("inline_prompt") - @ExcludeMissing + /** Alias for calling [Builder.inlinePrompt] with `inlinePrompt.orElse(null)`. */ + fun inlinePrompt(inlinePrompt: Optional) = + inlinePrompt(inlinePrompt.getOrNull()) + + /** + * Sets [Builder.inlinePrompt] to an arbitrary JSON value. + * + * You should usually call [Builder.inlinePrompt] with a well-typed [PromptData] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ fun inlinePrompt(inlinePrompt: JsonField) = apply { this.inlinePrompt = inlinePrompt } /** The name of the inline prompt */ - fun name(name: String) = name(JsonField.of(name)) + fun name(name: String?) = name(JsonField.ofNullable(name)) - /** The name of the inline prompt */ - @JsonProperty("name") - @ExcludeMissing + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2004,901 +5991,926 @@ constructor( 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 [InlinePrompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .inlinePrompt() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): InlinePrompt = InlinePrompt( - inlinePrompt, + checkRequired("inlinePrompt", inlinePrompt), name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - } - - @JsonDeserialize(using = Task.Deserializer::class) - @JsonSerialize(using = Task.Serializer::class) - class Task - private constructor( - private val functionId: FunctionId? = null, - private val projectSlug: ProjectSlug? = null, - private val globalFunction: GlobalFunction? = null, - private val promptSessionId: PromptSessionId? = null, - private val inlineCode: InlineCode? = null, - private val inlinePrompt: InlinePrompt? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false - - /** Function id */ - fun functionId(): Optional = Optional.ofNullable(functionId) - /** Project name and slug */ - fun projectSlug(): Optional = Optional.ofNullable(projectSlug) - /** Global function name */ - fun globalFunction(): Optional = Optional.ofNullable(globalFunction) - /** Prompt session id */ - fun promptSessionId(): Optional = Optional.ofNullable(promptSessionId) - /** Inline code function */ - fun inlineCode(): Optional = Optional.ofNullable(inlineCode) - /** Inline prompt definition */ - fun inlinePrompt(): Optional = Optional.ofNullable(inlinePrompt) - - fun isFunctionId(): Boolean = functionId != null - - fun isProjectSlug(): Boolean = projectSlug != null - - fun isGlobalFunction(): Boolean = globalFunction != null - - fun isPromptSessionId(): Boolean = promptSessionId != null - - fun isInlineCode(): Boolean = inlineCode != null - - fun isInlinePrompt(): Boolean = inlinePrompt != null - - fun asFunctionId(): FunctionId = functionId.getOrThrow("functionId") - - fun asProjectSlug(): ProjectSlug = projectSlug.getOrThrow("projectSlug") - - fun asGlobalFunction(): GlobalFunction = globalFunction.getOrThrow("globalFunction") - - fun asPromptSessionId(): PromptSessionId = promptSessionId.getOrThrow("promptSessionId") - - fun asInlineCode(): InlineCode = inlineCode.getOrThrow("inlineCode") - - fun asInlinePrompt(): InlinePrompt = inlinePrompt.getOrThrow("inlinePrompt") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T { - return when { - functionId != null -> visitor.visitFunctionId(functionId) - projectSlug != null -> visitor.visitProjectSlug(projectSlug) - globalFunction != null -> visitor.visitGlobalFunction(globalFunction) - promptSessionId != null -> visitor.visitPromptSessionId(promptSessionId) - inlineCode != null -> visitor.visitInlineCode(inlineCode) - inlinePrompt != null -> visitor.visitInlinePrompt(inlinePrompt) - else -> visitor.unknown(_json) - } - } - - fun validate(): Task = apply { - if (!validated) { - if ( - functionId == null && - projectSlug == null && - globalFunction == null && - promptSessionId == null && - inlineCode == null && - inlinePrompt == null - ) { - throw BraintrustInvalidDataException("Unknown Task: $_json") - } - functionId?.validate() - projectSlug?.validate() - globalFunction?.validate() - promptSessionId?.validate() - inlineCode?.validate() - inlinePrompt?.validate() - validated = true - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Task && - this.functionId == other.functionId && - this.projectSlug == other.projectSlug && - this.globalFunction == other.globalFunction && - this.promptSessionId == other.promptSessionId && - this.inlineCode == other.inlineCode && - this.inlinePrompt == other.inlinePrompt - } - override fun hashCode(): Int { - return Objects.hash( - functionId, - projectSlug, - globalFunction, - promptSessionId, - inlineCode, - inlinePrompt, - ) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun toString(): String { - return when { - functionId != null -> "Task{functionId=$functionId}" - projectSlug != null -> "Task{projectSlug=$projectSlug}" - globalFunction != null -> "Task{globalFunction=$globalFunction}" - promptSessionId != null -> "Task{promptSessionId=$promptSessionId}" - inlineCode != null -> "Task{inlineCode=$inlineCode}" - inlinePrompt != null -> "Task{inlinePrompt=$inlinePrompt}" - _json != null -> "Task{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Task") + return /* spotless:off */ other is InlinePrompt && inlinePrompt == other.inlinePrompt && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } - } - companion object { - - @JvmStatic fun ofFunctionId(functionId: FunctionId) = Task(functionId = functionId) - - @JvmStatic fun ofProjectSlug(projectSlug: ProjectSlug) = Task(projectSlug = projectSlug) - - @JvmStatic - fun ofGlobalFunction(globalFunction: GlobalFunction) = - Task(globalFunction = globalFunction) - - @JvmStatic - fun ofPromptSessionId(promptSessionId: PromptSessionId) = - Task(promptSessionId = promptSessionId) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(inlinePrompt, name, additionalProperties) } + /* spotless:on */ - @JvmStatic fun ofInlineCode(inlineCode: InlineCode) = Task(inlineCode = inlineCode) + override fun hashCode(): Int = hashCode - @JvmStatic - fun ofInlinePrompt(inlinePrompt: InlinePrompt) = Task(inlinePrompt = inlinePrompt) + override fun toString() = + "InlinePrompt{inlinePrompt=$inlinePrompt, name=$name, additionalProperties=$additionalProperties}" } + } - interface Visitor { - - fun visitFunctionId(functionId: FunctionId): T - - fun visitProjectSlug(projectSlug: ProjectSlug): T - - fun visitGlobalFunction(globalFunction: GlobalFunction): T + /** + * Optional settings for collecting git metadata. By default, will collect all git metadata + * fields allowed in org-level settings. + */ + @NoAutoDetect + class GitMetadataSettings + @JsonCreator + private constructor( + @JsonProperty("collect") + @ExcludeMissing + private val collect: JsonField = JsonMissing.of(), + @JsonProperty("fields") + @ExcludeMissing + private val fields: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { - fun visitPromptSessionId(promptSessionId: PromptSessionId): T + /** + * @throws BraintrustInvalidDataException 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 collect(): Collect = collect.getRequired("collect") - fun visitInlineCode(inlineCode: InlineCode): T + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun fields(): Optional> = Optional.ofNullable(fields.getNullable("fields")) - fun visitInlinePrompt(inlinePrompt: InlinePrompt): T + /** + * Returns the raw JSON value of [collect]. + * + * Unlike [collect], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("collect") @ExcludeMissing fun _collect(): JsonField = collect - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Task: $json") - } - } + /** + * Returns the raw JSON value of [fields]. + * + * Unlike [fields], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("fields") @ExcludeMissing fun _fields(): JsonField> = fields - class Deserializer : BaseDeserializer(Task::class) { + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - override fun ObjectCodec.deserialize(node: JsonNode): Task { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(functionId = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(projectSlug = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(globalFunction = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(promptSessionId = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(inlineCode = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Task(inlinePrompt = it, _json = json) - } + private var validated: Boolean = false - return Task(_json = json) + fun validate(): GitMetadataSettings = apply { + if (validated) { + return@apply } - } - class Serializer : BaseSerializer(Task::class) { - - override fun serialize( - value: Task, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.functionId != null -> generator.writeObject(value.functionId) - value.projectSlug != null -> generator.writeObject(value.projectSlug) - value.globalFunction != null -> generator.writeObject(value.globalFunction) - value.promptSessionId != null -> generator.writeObject(value.promptSessionId) - value.inlineCode != null -> generator.writeObject(value.inlineCode) - value.inlinePrompt != null -> generator.writeObject(value.inlinePrompt) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Task") - } - } + collect() + fields() + validated = true } - /** Function id */ - @JsonDeserialize(builder = FunctionId.Builder::class) - @NoAutoDetect - class FunctionId - private constructor( - private val functionId: JsonField, - private val version: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The ID of the function */ - fun functionId(): String = functionId.getRequired("function_id") - - /** The version of the function */ - fun version(): Optional = Optional.ofNullable(version.getNullable("version")) - - /** The ID of the function */ - @JsonProperty("function_id") @ExcludeMissing fun _functionId() = functionId - - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): FunctionId = apply { - if (!validated) { - functionId() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun toBuilder() = Builder().from(this) - return other is FunctionId && - this.functionId == other.functionId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } + companion object { - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - functionId, - version, - additionalProperties, - ) - } - return hashCode - } + /** + * Returns a mutable builder for constructing an instance of [GitMetadataSettings]. + * + * The following fields are required: + * ```java + * .collect() + * ``` + */ + @JvmStatic fun builder() = Builder() + } - override fun toString() = - "FunctionId{functionId=$functionId, version=$version, additionalProperties=$additionalProperties}" + /** A builder for [GitMetadataSettings]. */ + class Builder internal constructor() { - companion object { + private var collect: JsonField? = null + private var fields: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() - @JvmStatic fun builder() = Builder() + @JvmSynthetic + internal fun from(gitMetadataSettings: GitMetadataSettings) = apply { + collect = gitMetadataSettings.collect + fields = gitMetadataSettings.fields.map { it.toMutableList() } + additionalProperties = gitMetadataSettings.additionalProperties.toMutableMap() } - class Builder { - - private var functionId: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun collect(collect: Collect) = collect(JsonField.of(collect)) - @JvmSynthetic - internal fun from(functionId: FunctionId) = apply { - this.functionId = functionId.functionId - this.version = functionId.version - additionalProperties(functionId.additionalProperties) - } + /** + * Sets [Builder.collect] to an arbitrary JSON value. + * + * You should usually call [Builder.collect] with a well-typed [Collect] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun collect(collect: JsonField) = apply { this.collect = collect } - /** The ID of the function */ - fun functionId(functionId: String) = functionId(JsonField.of(functionId)) + fun fields(fields: List) = fields(JsonField.of(fields)) - /** The ID of the function */ - @JsonProperty("function_id") - @ExcludeMissing - fun functionId(functionId: JsonField) = apply { - this.functionId = functionId - } + /** + * Sets [Builder.fields] to an arbitrary JSON value. + * + * You should usually call [Builder.fields] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun fields(fields: JsonField>) = apply { + this.fields = fields.map { it.toMutableList() } + } - /** The version of the function */ - fun version(version: String) = version(JsonField.of(version)) + /** + * Adds a single [Field] to [fields]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addField(field: Field) = apply { + fields = + (fields ?: JsonField.of(mutableListOf())).also { + checkKnown("fields", it).add(field) + } + } - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing - fun version(version: JsonField) = apply { this.version = version } + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun build(): FunctionId = - FunctionId( - functionId, - version, - additionalProperties.toUnmodifiable(), - ) + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } + + /** + * Returns an immutable instance of [GitMetadataSettings]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .collect() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): GitMetadataSettings = + GitMetadataSettings( + checkRequired("collect", collect), + (fields ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) } - /** Project name and slug */ - @JsonDeserialize(builder = ProjectSlug.Builder::class) - @NoAutoDetect - class ProjectSlug - private constructor( - private val projectName: JsonField, - private val slug: JsonField, - private val version: JsonField, - private val additionalProperties: Map, - ) { + class Collect @JsonCreator private constructor(private val value: JsonField) : + Enum { - private var validated: Boolean = false + /** + * 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 - private var hashCode: Int = 0 + companion object { - /** The name of the project containing the function */ - fun projectName(): String = projectName.getRequired("project_name") + @JvmField val ALL = of("all") - /** The slug of the function */ - fun slug(): String = slug.getRequired("slug") + @JvmField val NONE = of("none") - /** The version of the function */ - fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + @JvmField val SOME = of("some") - /** The name of the project containing the function */ - @JsonProperty("project_name") @ExcludeMissing fun _projectName() = projectName + @JvmStatic fun of(value: String) = Collect(JsonField.of(value)) + } - /** The slug of the function */ - @JsonProperty("slug") @ExcludeMissing fun _slug() = slug + /** An enum containing [Collect]'s known values. */ + enum class Known { + ALL, + NONE, + SOME, + } - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * An enum containing [Collect]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Collect] 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 { + ALL, + NONE, + SOME, + /** + * An enum member indicating that [Collect] was instantiated with an unknown value. + */ + _UNKNOWN, + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** + * 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) { + ALL -> Value.ALL + NONE -> Value.NONE + SOME -> Value.SOME + else -> Value._UNKNOWN + } - fun validate(): ProjectSlug = apply { - if (!validated) { - projectName() - slug() - version() - validated = true + /** + * 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + ALL -> Known.ALL + NONE -> Known.NONE + SOME -> Known.SOME + else -> throw BraintrustInvalidDataException("Unknown Collect: $value") } - } - fun toBuilder() = Builder().from(this) + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is ProjectSlug && - this.projectName == other.projectName && - this.slug == other.slug && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectName, - slug, - version, - additionalProperties, - ) - } - return hashCode + return /* spotless:off */ other is Collect && value == other.value /* spotless:on */ } - override fun toString() = - "ProjectSlug{projectName=$projectName, slug=$slug, version=$version, additionalProperties=$additionalProperties}" - - companion object { + override fun hashCode() = value.hashCode() - @JvmStatic fun builder() = Builder() - } + override fun toString() = value.toString() + } - class Builder { + class Field @JsonCreator private constructor(private val value: JsonField) : Enum { - private var projectName: JsonField = JsonMissing.of() - private var slug: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** + * 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 - @JvmSynthetic - internal fun from(projectSlug: ProjectSlug) = apply { - this.projectName = projectSlug.projectName - this.slug = projectSlug.slug - this.version = projectSlug.version - additionalProperties(projectSlug.additionalProperties) - } + companion object { - /** The name of the project containing the function */ - fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + @JvmField val COMMIT = of("commit") - /** The name of the project containing the function */ - @JsonProperty("project_name") - @ExcludeMissing - fun projectName(projectName: JsonField) = apply { - this.projectName = projectName - } + @JvmField val BRANCH = of("branch") - /** The slug of the function */ - fun slug(slug: String) = slug(JsonField.of(slug)) + @JvmField val TAG = of("tag") - /** The slug of the function */ - @JsonProperty("slug") - @ExcludeMissing - fun slug(slug: JsonField) = apply { this.slug = slug } + @JvmField val DIRTY = of("dirty") - /** The version of the function */ - fun version(version: String) = version(JsonField.of(version)) + @JvmField val AUTHOR_NAME = of("author_name") - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing - fun version(version: JsonField) = apply { this.version = version } + @JvmField val AUTHOR_EMAIL = of("author_email") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + @JvmField val COMMIT_MESSAGE = of("commit_message") - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + @JvmField val COMMIT_TIME = of("commit_time") - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + @JvmField val GIT_DIFF = of("git_diff") - fun build(): ProjectSlug = - ProjectSlug( - projectName, - slug, - version, - additionalProperties.toUnmodifiable(), - ) + @JvmStatic fun of(value: String) = Field(JsonField.of(value)) } - } - - /** Global function name */ - @JsonDeserialize(builder = GlobalFunction.Builder::class) - @NoAutoDetect - class GlobalFunction - private constructor( - private val globalFunction: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - private var hashCode: Int = 0 + /** An enum containing [Field]'s known values. */ + enum class Known { + COMMIT, + BRANCH, + TAG, + DIRTY, + AUTHOR_NAME, + AUTHOR_EMAIL, + COMMIT_MESSAGE, + COMMIT_TIME, + GIT_DIFF, + } /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals + * An enum containing [Field]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Field] 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. */ - fun globalFunction(): String = globalFunction.getRequired("global_function") + enum class Value { + COMMIT, + BRANCH, + TAG, + DIRTY, + AUTHOR_NAME, + AUTHOR_EMAIL, + COMMIT_MESSAGE, + COMMIT_TIME, + GIT_DIFF, + /** + * An enum member indicating that [Field] was instantiated with an unknown value. + */ + _UNKNOWN, + } /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals + * 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. */ - @JsonProperty("global_function") @ExcludeMissing fun _globalFunction() = globalFunction - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun value(): Value = + when (this) { + COMMIT -> Value.COMMIT + BRANCH -> Value.BRANCH + TAG -> Value.TAG + DIRTY -> Value.DIRTY + AUTHOR_NAME -> Value.AUTHOR_NAME + AUTHOR_EMAIL -> Value.AUTHOR_EMAIL + COMMIT_MESSAGE -> Value.COMMIT_MESSAGE + COMMIT_TIME -> Value.COMMIT_TIME + GIT_DIFF -> Value.GIT_DIFF + else -> Value._UNKNOWN + } - fun validate(): GlobalFunction = apply { - if (!validated) { - globalFunction() - validated = true + /** + * 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + COMMIT -> Known.COMMIT + BRANCH -> Known.BRANCH + TAG -> Known.TAG + DIRTY -> Known.DIRTY + AUTHOR_NAME -> Known.AUTHOR_NAME + AUTHOR_EMAIL -> Known.AUTHOR_EMAIL + COMMIT_MESSAGE -> Known.COMMIT_MESSAGE + COMMIT_TIME -> Known.COMMIT_TIME + GIT_DIFF -> Known.GIT_DIFF + else -> throw BraintrustInvalidDataException("Unknown Field: $value") } - } - fun toBuilder() = Builder().from(this) + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is GlobalFunction && - this.globalFunction == other.globalFunction && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Field && value == other.value /* spotless:on */ } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(globalFunction, additionalProperties) - } - return hashCode + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun toString() = - "GlobalFunction{globalFunction=$globalFunction, additionalProperties=$additionalProperties}" + return /* spotless:off */ other is GitMetadataSettings && collect == other.collect && fields == other.fields && additionalProperties == other.additionalProperties /* spotless:on */ + } - companion object { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(collect, fields, additionalProperties) } + /* spotless:on */ - @JvmStatic fun builder() = Builder() + override fun hashCode(): Int = hashCode + + override fun toString() = + "GitMetadataSettings{collect=$collect, fields=$fields, additionalProperties=$additionalProperties}" + } + + /** + * Optional experiment-level metadata to store about the evaluation. You can later use this to + * slice & dice across experiments. + */ + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply } - class Builder { + validated = true + } - private var globalFunction: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun toBuilder() = Builder().from(this) - @JvmSynthetic - internal fun from(globalFunction: GlobalFunction) = apply { - this.globalFunction = globalFunction.globalFunction - additionalProperties(globalFunction.additionalProperties) - } + companion object { - /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals - */ - fun globalFunction(globalFunction: String) = - globalFunction(JsonField.of(globalFunction)) + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } - /** - * The name of the global function. Currently, the global namespace includes the - * functions in autoevals - */ - @JsonProperty("global_function") - @ExcludeMissing - fun globalFunction(globalFunction: JsonField) = apply { - this.globalFunction = globalFunction - } + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun build(): GlobalFunction = - GlobalFunction(globalFunction, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } - /** Prompt session id */ - @JsonDeserialize(builder = PromptSessionId.Builder::class) - @NoAutoDetect - class PromptSessionId - private constructor( - private val promptSessionId: JsonField, - private val promptSessionFunctionId: JsonField, - private val version: JsonField, - private val additionalProperties: Map, - ) { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - private var validated: Boolean = false + override fun hashCode(): Int = hashCode - private var hashCode: Int = 0 + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } - /** The ID of the prompt session */ - fun promptSessionId(): String = promptSessionId.getRequired("prompt_session_id") + /** Options for tracing the evaluation */ + @JsonDeserialize(using = Parent.Deserializer::class) + @JsonSerialize(using = Parent.Serializer::class) + class Parent + private constructor( + private val spanParentStruct: SpanParentStruct? = null, + private val string: String? = null, + private val _json: JsonValue? = null, + ) { - /** The ID of the function in the prompt session */ - fun promptSessionFunctionId(): String = - promptSessionFunctionId.getRequired("prompt_session_function_id") + /** Span parent properties */ + fun spanParentStruct(): Optional = Optional.ofNullable(spanParentStruct) - /** The version of the function */ - fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + /** The parent's span identifier, created by calling `.export()` on a span */ + fun string(): Optional = Optional.ofNullable(string) - /** The ID of the prompt session */ - @JsonProperty("prompt_session_id") - @ExcludeMissing - fun _promptSessionId() = promptSessionId + fun isSpanParentStruct(): Boolean = spanParentStruct != null - /** The ID of the function in the prompt session */ - @JsonProperty("prompt_session_function_id") - @ExcludeMissing - fun _promptSessionFunctionId() = promptSessionFunctionId + fun isString(): Boolean = string != null - /** The version of the function */ - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** Span parent properties */ + fun asSpanParentStruct(): SpanParentStruct = spanParentStruct.getOrThrow("spanParentStruct") - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** The parent's span identifier, created by calling `.export()` on a span */ + fun asString(): String = string.getOrThrow("string") - fun validate(): PromptSessionId = apply { - if (!validated) { - promptSessionId() - promptSessionFunctionId() - version() - validated = true - } - } + fun _json(): Optional = Optional.ofNullable(_json) - fun toBuilder() = Builder().from(this) + fun accept(visitor: Visitor): T { + return when { + spanParentStruct != null -> visitor.visitSpanParentStruct(spanParentStruct) + string != null -> visitor.visitString(string) + else -> visitor.unknown(_json) + } + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + private var validated: Boolean = false - return other is PromptSessionId && - this.promptSessionId == other.promptSessionId && - this.promptSessionFunctionId == other.promptSessionFunctionId && - this.version == other.version && - this.additionalProperties == other.additionalProperties + fun validate(): Parent = apply { + if (validated) { + return@apply } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - promptSessionId, - promptSessionFunctionId, - version, - additionalProperties, - ) + accept( + object : Visitor { + override fun visitSpanParentStruct(spanParentStruct: SpanParentStruct) { + spanParentStruct.validate() + } + + override fun visitString(string: String) {} } - return hashCode + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun toString() = - "PromptSessionId{promptSessionId=$promptSessionId, promptSessionFunctionId=$promptSessionFunctionId, version=$version, additionalProperties=$additionalProperties}" + return /* spotless:off */ other is Parent && spanParentStruct == other.spanParentStruct && string == other.string /* spotless:on */ + } - companion object { + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanParentStruct, string) /* spotless:on */ - @JvmStatic fun builder() = Builder() + override fun toString(): String = + when { + spanParentStruct != null -> "Parent{spanParentStruct=$spanParentStruct}" + string != null -> "Parent{string=$string}" + _json != null -> "Parent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Parent") } - class Builder { + companion object { - private var promptSessionId: JsonField = JsonMissing.of() - private var promptSessionFunctionId: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** Span parent properties */ + @JvmStatic + fun ofSpanParentStruct(spanParentStruct: SpanParentStruct) = + Parent(spanParentStruct = spanParentStruct) - @JvmSynthetic - internal fun from(promptSessionId: PromptSessionId) = apply { - this.promptSessionId = promptSessionId.promptSessionId - this.promptSessionFunctionId = promptSessionId.promptSessionFunctionId - this.version = promptSessionId.version - additionalProperties(promptSessionId.additionalProperties) - } + /** The parent's span identifier, created by calling `.export()` on a span */ + @JvmStatic fun ofString(string: String) = Parent(string = string) + } - /** The ID of the prompt session */ - fun promptSessionId(promptSessionId: String) = - promptSessionId(JsonField.of(promptSessionId)) + /** An interface that defines how to map each variant of [Parent] to a value of type [T]. */ + interface Visitor { - /** The ID of the prompt session */ - @JsonProperty("prompt_session_id") - @ExcludeMissing - fun promptSessionId(promptSessionId: JsonField) = apply { - this.promptSessionId = promptSessionId - } + /** Span parent properties */ + fun visitSpanParentStruct(spanParentStruct: SpanParentStruct): T - /** The ID of the function in the prompt session */ - fun promptSessionFunctionId(promptSessionFunctionId: String) = - promptSessionFunctionId(JsonField.of(promptSessionFunctionId)) + /** The parent's span identifier, created by calling `.export()` on a span */ + fun visitString(string: String): T - /** The ID of the function in the prompt session */ - @JsonProperty("prompt_session_function_id") - @ExcludeMissing - fun promptSessionFunctionId(promptSessionFunctionId: JsonField) = apply { - this.promptSessionFunctionId = promptSessionFunctionId - } + /** + * Maps an unknown variant of [Parent] to a value of type [T]. + * + * An instance of [Parent] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Parent: $json") + } + } - /** The version of the function */ - fun version(version: String) = version(JsonField.of(version)) + internal class Deserializer : BaseDeserializer(Parent::class) { - /** The version of the function */ - @JsonProperty("version") - @ExcludeMissing - fun version(version: JsonField) = apply { this.version = version } + override fun ObjectCodec.deserialize(node: JsonNode): Parent { + val json = JsonValue.fromJsonNode(node) - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Parent(spanParentStruct = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef())?.let { + return Parent(string = it, _json = json) } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return Parent(_json = json) + } + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + internal class Serializer : BaseSerializer(Parent::class) { - fun build(): PromptSessionId = - PromptSessionId( - promptSessionId, - promptSessionFunctionId, - version, - additionalProperties.toUnmodifiable(), - ) + override fun serialize( + value: Parent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.spanParentStruct != null -> generator.writeObject(value.spanParentStruct) + value.string != null -> generator.writeObject(value.string) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Parent") + } } } - /** Inline code function */ - @JsonDeserialize(builder = InlineCode.Builder::class) + /** Span parent properties */ @NoAutoDetect - class InlineCode + class SpanParentStruct + @JsonCreator private constructor( - private val inlineContext: JsonField, - private val code: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("propagated_event") + @ExcludeMissing + private val propagatedEvent: JsonField = JsonMissing.of(), + @JsonProperty("row_ids") + @ExcludeMissing + private val rowIds: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * The id of the container object you are logging to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") - fun inlineContext(): InlineContext = inlineContext.getRequired("inline_context") + /** + * Include these properties in every span created under this parent + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun propagatedEvent(): Optional = + Optional.ofNullable(propagatedEvent.getNullable("propagated_event")) - /** The inline code to execute */ - fun code(): String = code.getRequired("code") + /** + * Identifiers for the row to to log a subspan under + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun rowIds(): Optional = Optional.ofNullable(rowIds.getNullable("row_ids")) - /** The name of the inline code function */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId - @JsonProperty("inline_context") @ExcludeMissing fun _inlineContext() = inlineContext + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType - /** The inline code to execute */ - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [propagatedEvent]. + * + * Unlike [propagatedEvent], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("propagated_event") + @ExcludeMissing + fun _propagatedEvent(): JsonField = propagatedEvent - /** The name of the inline code function */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [rowIds]. + * + * Unlike [rowIds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("row_ids") @ExcludeMissing fun _rowIds(): JsonField = rowIds @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): InlineCode = apply { - if (!validated) { - inlineContext().validate() - code() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): SpanParentStruct = apply { + if (validated) { + return@apply } - return other is InlineCode && - this.inlineContext == other.inlineContext && - this.code == other.code && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - inlineContext, - code, - name, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + propagatedEvent().ifPresent { it.validate() } + rowIds().ifPresent { it.validate() } + validated = true } - override fun toString() = - "InlineCode{inlineContext=$inlineContext, code=$code, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [SpanParentStruct]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [SpanParentStruct]. */ + class Builder internal constructor() { - private var inlineContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var propagatedEvent: JsonField = JsonMissing.of() + private var rowIds: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(inlineCode: InlineCode) = apply { - this.inlineContext = inlineCode.inlineContext - this.code = inlineCode.code - this.name = inlineCode.name - additionalProperties(inlineCode.additionalProperties) + internal fun from(spanParentStruct: SpanParentStruct) = apply { + objectId = spanParentStruct.objectId + objectType = spanParentStruct.objectType + propagatedEvent = spanParentStruct.propagatedEvent + rowIds = spanParentStruct.rowIds + additionalProperties = spanParentStruct.additionalProperties.toMutableMap() } - fun inlineContext(inlineContext: InlineContext) = - inlineContext(JsonField.of(inlineContext)) + /** The id of the container object you are logging to */ + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - @JsonProperty("inline_context") - @ExcludeMissing - fun inlineContext(inlineContext: JsonField) = apply { - this.inlineContext = inlineContext + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType } - /** The inline code to execute */ - fun code(code: String) = code(JsonField.of(code)) + /** Include these properties in every span created under this parent */ + fun propagatedEvent(propagatedEvent: PropagatedEvent?) = + propagatedEvent(JsonField.ofNullable(propagatedEvent)) - /** The inline code to execute */ - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } + /** + * Alias for calling [Builder.propagatedEvent] with `propagatedEvent.orElse(null)`. + */ + fun propagatedEvent(propagatedEvent: Optional) = + propagatedEvent(propagatedEvent.getOrNull()) - /** The name of the inline code function */ - fun name(name: String) = name(JsonField.of(name)) + /** + * Sets [Builder.propagatedEvent] to an arbitrary JSON value. + * + * You should usually call [Builder.propagatedEvent] with a well-typed + * [PropagatedEvent] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun propagatedEvent(propagatedEvent: JsonField) = apply { + this.propagatedEvent = propagatedEvent + } - /** The name of the inline code function */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** Identifiers for the row to to log a subspan under */ + fun rowIds(rowIds: RowIds?) = rowIds(JsonField.ofNullable(rowIds)) + + /** Alias for calling [Builder.rowIds] with `rowIds.orElse(null)`. */ + fun rowIds(rowIds: Optional) = rowIds(rowIds.getOrNull()) + + /** + * Sets [Builder.rowIds] to an arbitrary JSON value. + * + * You should usually call [Builder.rowIds] with a well-typed [RowIds] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun rowIds(rowIds: JsonField) = apply { this.rowIds = rowIds } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2906,114 +6918,198 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): InlineCode = - InlineCode( - inlineContext, - code, - name, - additionalProperties.toUnmodifiable(), + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SpanParentStruct]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanParentStruct = + SpanParentStruct( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + propagatedEvent, + rowIds, + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = InlineContext.Builder::class) - @NoAutoDetect - class InlineContext - private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, - ) { + class ObjectType + @JsonCreator + private constructor(private val value: JsonField) : Enum { - private var validated: Boolean = false + /** + * 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 PROJECT_LOGS = of("project_logs") + + @JvmField val EXPERIMENT = of("experiment") + + @JvmField val PLAYGROUND_LOGS = of("playground_logs") + + @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + } + + /** An enum containing [ObjectType]'s known values. */ + enum class Known { + PROJECT_LOGS, + EXPERIMENT, + PLAYGROUND_LOGS, + } + + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { + PROJECT_LOGS, + EXPERIMENT, + PLAYGROUND_LOGS, + /** + * An enum member indicating that [ObjectType] 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) { + PROJECT_LOGS -> Value.PROJECT_LOGS + EXPERIMENT -> Value.EXPERIMENT + PLAYGROUND_LOGS -> Value.PLAYGROUND_LOGS + 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + PROJECT_LOGS -> Known.PROJECT_LOGS + EXPERIMENT -> Known.EXPERIMENT + PLAYGROUND_LOGS -> Known.PLAYGROUND_LOGS + else -> throw BraintrustInvalidDataException("Unknown ObjectType: $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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - private var hashCode: Int = 0 + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun runtime(): Runtime = runtime.getRequired("runtime") + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } - fun version(): String = version.getRequired("version") + override fun hashCode() = value.hashCode() - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime + override fun toString() = value.toString() + } - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** Include these properties in every span created under this parent */ + @NoAutoDetect + class PropagatedEvent + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): InlineContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): PropagatedEvent = apply { + if (validated) { + return@apply } - return other is InlineContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + validated = true } - override fun toString() = - "InlineContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PropagatedEvent]. + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [PropagatedEvent]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(inlineContext: InlineContext) = apply { - this.runtime = inlineContext.runtime - this.version = inlineContext.version - additionalProperties(inlineContext.additionalProperties) + internal fun from(propagatedEvent: PropagatedEvent) = apply { + additionalProperties = propagatedEvent.additionalProperties.toMutableMap() } - fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - - @JsonProperty("runtime") - @ExcludeMissing - fun runtime(runtime: JsonField) = apply { this.runtime = runtime } - - fun version(version: String) = version(JsonField.of(version)) - - @JsonProperty("version") - @ExcludeMissing - fun version(version: JsonField) = apply { this.version = version } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -3021,268 +7117,291 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): InlineContext = - InlineContext( - runtime, - version, - additionalProperties.toUnmodifiable(), - ) - } - - class Runtime - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val NODE = Runtime(JsonField.of("node")) - - @JvmField val PYTHON = Runtime(JsonField.of("python")) - - @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - enum class Known { - NODE, - PYTHON, - } + /** + * Returns an immutable instance of [PropagatedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PropagatedEvent = + PropagatedEvent(additionalProperties.toImmutable()) + } - enum class Value { - NODE, - PYTHON, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - NODE -> Value.NODE - PYTHON -> Value.PYTHON - else -> Value._UNKNOWN - } + return /* spotless:off */ other is PropagatedEvent && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun known(): Known = - when (this) { - NODE -> Known.NODE - PYTHON -> Known.PYTHON - else -> throw BraintrustInvalidDataException("Unknown Runtime: $value") - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun hashCode(): Int = hashCode + + override fun toString() = + "PropagatedEvent{additionalProperties=$additionalProperties}" } - } - /** Inline prompt definition */ - @JsonDeserialize(builder = InlinePrompt.Builder::class) - @NoAutoDetect - class InlinePrompt - private constructor( - private val inlinePrompt: JsonField, - private val name: JsonField, - private val additionalProperties: Map, - ) { + /** Identifiers for the row to to log a subspan under */ + @NoAutoDetect + class RowIds + @JsonCreator + private constructor( + @JsonProperty("id") + @ExcludeMissing + private val id: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { - private var validated: Boolean = false + /** + * The id of the row + * + * @throws BraintrustInvalidDataException 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") - private var hashCode: Int = 0 + /** + * The root_span_id of the row + * + * @throws BraintrustInvalidDataException 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 rootSpanId(): String = rootSpanId.getRequired("root_span_id") - /** The prompt, model, and its parameters */ - fun inlinePrompt(): Optional = - Optional.ofNullable(inlinePrompt.getNullable("inline_prompt")) + /** + * The span_id of the row + * + * @throws BraintrustInvalidDataException 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 spanId(): String = spanId.getRequired("span_id") - /** The name of the inline prompt */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + /** + * 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 - /** The prompt, model, and its parameters */ - @JsonProperty("inline_prompt") @ExcludeMissing fun _inlinePrompt() = inlinePrompt + /** + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("root_span_id") + @ExcludeMissing + fun _rootSpanId(): JsonField = rootSpanId - /** The name of the inline prompt */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - fun validate(): InlinePrompt = apply { - if (!validated) { - inlinePrompt().map { it.validate() } - name() - validated = true - } - } + private var validated: Boolean = false - fun toBuilder() = Builder().from(this) + fun validate(): RowIds = apply { + if (validated) { + return@apply + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + id() + rootSpanId() + spanId() + validated = true } - return other is InlinePrompt && - this.inlinePrompt == other.inlinePrompt && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } + fun toBuilder() = Builder().from(this) - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - inlinePrompt, - name, - additionalProperties, - ) + companion object { + + /** + * Returns a mutable builder for constructing an instance of [RowIds]. + * + * The following fields are required: + * ```java + * .id() + * .rootSpanId() + * .spanId() + * ``` + */ + @JvmStatic fun builder() = Builder() } - return hashCode - } - override fun toString() = - "InlinePrompt{inlinePrompt=$inlinePrompt, name=$name, additionalProperties=$additionalProperties}" + /** A builder for [RowIds]. */ + class Builder internal constructor() { - companion object { + private var id: JsonField? = null + private var rootSpanId: JsonField? = null + private var spanId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() - @JvmStatic fun builder() = Builder() - } + @JvmSynthetic + internal fun from(rowIds: RowIds) = apply { + id = rowIds.id + rootSpanId = rowIds.rootSpanId + spanId = rowIds.spanId + additionalProperties = rowIds.additionalProperties.toMutableMap() + } - class Builder { + /** The id of the row */ + 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 } + + /** The root_span_id of the row */ + fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) + + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { + this.rootSpanId = rootSpanId + } - private var inlinePrompt: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** The span_id of the row */ + fun spanId(spanId: String) = spanId(JsonField.of(spanId)) - @JvmSynthetic - internal fun from(inlinePrompt: InlinePrompt) = apply { - this.inlinePrompt = inlinePrompt.inlinePrompt - this.name = inlinePrompt.name - additionalProperties(inlinePrompt.additionalProperties) - } + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } - /** The prompt, model, and its parameters */ - fun inlinePrompt(inlinePrompt: PromptData) = - inlinePrompt(JsonField.of(inlinePrompt)) + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** The prompt, model, and its parameters */ - @JsonProperty("inline_prompt") - @ExcludeMissing - fun inlinePrompt(inlinePrompt: JsonField) = apply { - this.inlinePrompt = inlinePrompt - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** The name of the inline prompt */ - fun name(name: String) = name(JsonField.of(name)) + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - /** The name of the inline prompt */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + /** + * Returns an immutable instance of [RowIds]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .rootSpanId() + * .spanId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): RowIds = + RowIds( + checkRequired("id", id), + checkRequired("rootSpanId", rootSpanId), + checkRequired("spanId", spanId), + additionalProperties.toImmutable(), + ) } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun build(): InlinePrompt = - InlinePrompt( - inlinePrompt, - name, - additionalProperties.toUnmodifiable(), - ) - } - } - } - - /** - * Optional experiment-level metadata to store about the evaluation. You can later use this to - * slice & dice across experiments. - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var hashCode: Int = 0 + return /* spotless:off */ other is RowIds && id == other.id && rootSpanId == other.rootSpanId && spanId == other.spanId && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, rootSpanId, spanId, additionalProperties) } + /* spotless:on */ - fun toBuilder() = Builder().from(this) + override fun hashCode(): Int = hashCode - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun toString() = + "RowIds{id=$id, rootSpanId=$rootSpanId, spanId=$spanId, additionalProperties=$additionalProperties}" } - return other is Metadata && this.additionalProperties == other.additionalProperties - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) + return /* spotless:off */ other is SpanParentStruct && objectId == other.objectId && objectType == other.objectType && propagatedEvent == other.propagatedEvent && rowIds == other.rowIds && additionalProperties == other.additionalProperties /* spotless:on */ } - return hashCode - } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, propagatedEvent, rowIds, additionalProperties) } + /* spotless:on */ - companion object { + override fun hashCode(): Int = hashCode - @JvmStatic fun builder() = Builder() + override fun toString() = + "SpanParentStruct{objectId=$objectId, objectType=$objectType, propagatedEvent=$propagatedEvent, rowIds=$rowIds, additionalProperties=$additionalProperties}" } + } - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return /* spotless:off */ other is EvalCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } + override fun toString() = + "EvalCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Experiment.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Experiment.kt index 7e07bb42..78d87c27 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Experiment.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Experiment.kt @@ -7,489 +7,725 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Experiment.Builder::class) @NoAutoDetect class Experiment +@JsonCreator private constructor( - private val id: JsonField, - private val projectId: JsonField, - private val name: JsonField, - private val description: JsonField, - private val created: JsonField, - private val repoInfo: JsonField, - private val commit: JsonField, - private val baseExpId: JsonField, - private val deletedAt: JsonField, - private val datasetId: JsonField, - private val datasetVersion: JsonField, - private val public_: JsonField, - private val userId: JsonField, - private val metadata: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("public") + @ExcludeMissing + private val public_: JsonField = JsonMissing.of(), + @JsonProperty("base_exp_id") + @ExcludeMissing + private val baseExpId: JsonField = JsonMissing.of(), + @JsonProperty("commit") + @ExcludeMissing + private val commit: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("dataset_id") + @ExcludeMissing + private val datasetId: JsonField = JsonMissing.of(), + @JsonProperty("dataset_version") + @ExcludeMissing + private val datasetVersion: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("repo_info") + @ExcludeMissing + private val repoInfo: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the experiment */ + /** + * Unique identifier for the experiment + * + * @throws BraintrustInvalidDataException 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") - /** Unique identifier for the project that the experiment belongs under */ - fun projectId(): String = projectId.getRequired("project_id") - - /** Name of the experiment. Within a project, experiment names are unique */ + /** + * Name of the experiment. Within a project, experiment names are unique + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the experiment */ - fun description(): Optional = - Optional.ofNullable(description.getNullable("description")) + /** + * Unique identifier for the project that the experiment belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Date of experiment creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + /** + * Whether or not the experiment is public. Public experiments can be viewed by anybody inside + * or outside the organization + * + * @throws BraintrustInvalidDataException 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 public_(): Boolean = public_.getRequired("public") - /** Metadata about the state of the repo when the experiment was created */ - fun repoInfo(): Optional = Optional.ofNullable(repoInfo.getNullable("repo_info")) + /** + * Id of default base experiment to compare against when viewing this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baseExpId(): Optional = Optional.ofNullable(baseExpId.getNullable("base_exp_id")) - /** Commit, taken directly from `repo_info.commit` */ + /** + * Commit, taken directly from `repo_info.commit` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun commit(): Optional = Optional.ofNullable(commit.getNullable("commit")) - /** Id of default base experiment to compare against when viewing this experiment */ - fun baseExpId(): Optional = Optional.ofNullable(baseExpId.getNullable("base_exp_id")) - - /** Date of experiment deletion, or null if the experiment is still active */ - fun deletedAt(): Optional = - Optional.ofNullable(deletedAt.getNullable("deleted_at")) + /** + * Date of experiment creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Identifier of the linked dataset, or null if the experiment is not linked to a dataset */ + /** + * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun datasetId(): Optional = Optional.ofNullable(datasetId.getNullable("dataset_id")) /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun datasetVersion(): Optional = Optional.ofNullable(datasetVersion.getNullable("dataset_version")) /** - * Whether or not the experiment is public. Public experiments can be viewed by anybody inside - * or outside the organization + * Date of experiment deletion, or null if the experiment is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun public_(): Boolean = public_.getRequired("public") + fun deletedAt(): Optional = + Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Identifies the user who created the experiment */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + /** + * Textual description of the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** User-controlled metadata about the experiment */ + /** + * User-controlled metadata about the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** Unique identifier for the experiment */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun repoInfo(): Optional = Optional.ofNullable(repoInfo.getNullable("repo_info")) - /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Identifies the user who created the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 - /** Textual description of the experiment */ - @JsonProperty("description") @ExcludeMissing fun _description() = description + /** + * 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 - /** Date of experiment creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId - /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") @ExcludeMissing fun _repoInfo() = repoInfo + /** + * Returns the raw JSON value of [public_]. + * + * Unlike [public_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("public") @ExcludeMissing fun _public_(): JsonField = public_ - /** Commit, taken directly from `repo_info.commit` */ - @JsonProperty("commit") @ExcludeMissing fun _commit() = commit + /** + * Returns the raw JSON value of [baseExpId]. + * + * Unlike [baseExpId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("base_exp_id") @ExcludeMissing fun _baseExpId(): JsonField = baseExpId - /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") @ExcludeMissing fun _baseExpId() = baseExpId + /** + * Returns the raw JSON value of [commit]. + * + * Unlike [commit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("commit") @ExcludeMissing fun _commit(): JsonField = commit - /** Date of experiment deletion, or null if the experiment is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** Identifier of the linked dataset, or null if the experiment is not linked to a dataset */ - @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId() = datasetId + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId(): JsonField = datasetId /** - * Version number of the linked dataset the experiment was run against. This can be used to - * reproduce the experiment after the dataset has been modified. + * Returns the raw JSON value of [datasetVersion]. + * + * Unlike [datasetVersion], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("dataset_version") @ExcludeMissing fun _datasetVersion() = datasetVersion + @JsonProperty("dataset_version") + @ExcludeMissing + fun _datasetVersion(): JsonField = datasetVersion /** - * Whether or not the experiment is public. Public experiments can be viewed by anybody inside - * or outside the organization + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("public") @ExcludeMissing fun _public_() = public_ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt - /** Identifies the user who created the experiment */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * 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 - /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("repo_info") @ExcludeMissing fun _repoInfo(): JsonField = repoInfo + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Experiment = apply { - if (!validated) { - id() - projectId() - name() - description() - created() - repoInfo().map { it.validate() } - commit() - baseExpId() - deletedAt() - datasetId() - datasetVersion() - public_() - userId() - metadata().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Experiment = apply { + if (validated) { + return@apply } - return other is Experiment && - this.id == other.id && - this.projectId == other.projectId && - this.name == other.name && - this.description == other.description && - this.created == other.created && - this.repoInfo == other.repoInfo && - this.commit == other.commit && - this.baseExpId == other.baseExpId && - this.deletedAt == other.deletedAt && - this.datasetId == other.datasetId && - this.datasetVersion == other.datasetVersion && - this.public_ == other.public_ && - this.userId == other.userId && - this.metadata == other.metadata && - this.additionalProperties == other.additionalProperties + id() + name() + projectId() + public_() + baseExpId() + commit() + created() + datasetId() + datasetVersion() + deletedAt() + description() + metadata().ifPresent { it.validate() } + repoInfo().ifPresent { it.validate() } + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - projectId, - name, - description, - created, - repoInfo, - commit, - baseExpId, - deletedAt, - datasetId, - datasetVersion, - public_, - userId, - metadata, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Experiment{id=$id, projectId=$projectId, name=$name, description=$description, created=$created, repoInfo=$repoInfo, commit=$commit, baseExpId=$baseExpId, deletedAt=$deletedAt, datasetId=$datasetId, datasetVersion=$datasetVersion, public_=$public_, userId=$userId, metadata=$metadata, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Experiment]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .public_() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Experiment]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var repoInfo: JsonField = JsonMissing.of() - private var commit: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var public_: JsonField? = null private var baseExpId: JsonField = JsonMissing.of() - private var deletedAt: JsonField = JsonMissing.of() + private var commit: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() private var datasetId: JsonField = JsonMissing.of() private var datasetVersion: JsonField = JsonMissing.of() - private var public_: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var deletedAt: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() + private var repoInfo: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(experiment: Experiment) = apply { - this.id = experiment.id - this.projectId = experiment.projectId - this.name = experiment.name - this.description = experiment.description - this.created = experiment.created - this.repoInfo = experiment.repoInfo - this.commit = experiment.commit - this.baseExpId = experiment.baseExpId - this.deletedAt = experiment.deletedAt - this.datasetId = experiment.datasetId - this.datasetVersion = experiment.datasetVersion - this.public_ = experiment.public_ - this.userId = experiment.userId - this.metadata = experiment.metadata - additionalProperties(experiment.additionalProperties) + id = experiment.id + name = experiment.name + projectId = experiment.projectId + public_ = experiment.public_ + baseExpId = experiment.baseExpId + commit = experiment.commit + created = experiment.created + datasetId = experiment.datasetId + datasetVersion = experiment.datasetVersion + deletedAt = experiment.deletedAt + description = experiment.description + metadata = experiment.metadata + repoInfo = experiment.repoInfo + userId = experiment.userId + additionalProperties = experiment.additionalProperties.toMutableMap() } /** Unique identifier for the experiment */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the experiment */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Unique identifier for the project that the experiment belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - - /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + /** + * 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 } /** Name of the experiment. Within a project, experiment names are unique */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } - /** Textual description of the experiment */ - fun description(description: String) = description(JsonField.of(description)) + /** Unique identifier for the project that the experiment belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Textual description of the experiment */ - @JsonProperty("description") - @ExcludeMissing - fun description(description: JsonField) = apply { this.description = description } + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - /** Date of experiment creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** + * Whether or not the experiment is public. Public experiments can be viewed by anybody + * inside or outside the organization + */ + fun public_(public_: Boolean) = public_(JsonField.of(public_)) - /** Date of experiment creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * Sets [Builder.public_] to an arbitrary JSON value. + * + * You should usually call [Builder.public_] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun public_(public_: JsonField) = apply { this.public_ = public_ } - /** Metadata about the state of the repo when the experiment was created */ - fun repoInfo(repoInfo: RepoInfo) = repoInfo(JsonField.of(repoInfo)) + /** Id of default base experiment to compare against when viewing this experiment */ + fun baseExpId(baseExpId: String?) = baseExpId(JsonField.ofNullable(baseExpId)) - /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") - @ExcludeMissing - fun repoInfo(repoInfo: JsonField) = apply { this.repoInfo = repoInfo } + /** Alias for calling [Builder.baseExpId] with `baseExpId.orElse(null)`. */ + fun baseExpId(baseExpId: Optional) = baseExpId(baseExpId.getOrNull()) - /** Commit, taken directly from `repo_info.commit` */ - fun commit(commit: String) = commit(JsonField.of(commit)) + /** + * Sets [Builder.baseExpId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExpId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun baseExpId(baseExpId: JsonField) = apply { this.baseExpId = baseExpId } /** Commit, taken directly from `repo_info.commit` */ - @JsonProperty("commit") - @ExcludeMissing - fun commit(commit: JsonField) = apply { this.commit = commit } + fun commit(commit: String?) = commit(JsonField.ofNullable(commit)) - /** Id of default base experiment to compare against when viewing this experiment */ - fun baseExpId(baseExpId: String) = baseExpId(JsonField.of(baseExpId)) + /** Alias for calling [Builder.commit] with `commit.orElse(null)`. */ + fun commit(commit: Optional) = commit(commit.getOrNull()) - /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") - @ExcludeMissing - fun baseExpId(baseExpId: JsonField) = apply { this.baseExpId = baseExpId } + /** + * Sets [Builder.commit] to an arbitrary JSON value. + * + * You should usually call [Builder.commit] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun commit(commit: JsonField) = apply { this.commit = commit } - /** Date of experiment deletion, or null if the experiment is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) + /** Date of experiment creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) - /** Date of experiment deletion, or null if the experiment is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing - fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) /** - * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun datasetId(datasetId: String) = datasetId(JsonField.of(datasetId)) + fun created(created: JsonField) = apply { this.created = created } /** * Identifier of the linked dataset, or null if the experiment is not linked to a dataset */ - @JsonProperty("dataset_id") - @ExcludeMissing + fun datasetId(datasetId: String?) = datasetId(JsonField.ofNullable(datasetId)) + + /** Alias for calling [Builder.datasetId] with `datasetId.orElse(null)`. */ + fun datasetId(datasetId: Optional) = datasetId(datasetId.getOrNull()) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. */ - fun datasetVersion(datasetVersion: String) = datasetVersion(JsonField.of(datasetVersion)) + fun datasetVersion(datasetVersion: String?) = + datasetVersion(JsonField.ofNullable(datasetVersion)) + + /** Alias for calling [Builder.datasetVersion] with `datasetVersion.orElse(null)`. */ + fun datasetVersion(datasetVersion: Optional) = + datasetVersion(datasetVersion.getOrNull()) /** - * Version number of the linked dataset the experiment was run against. This can be used to - * reproduce the experiment after the dataset has been modified. + * Sets [Builder.datasetVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("dataset_version") - @ExcludeMissing fun datasetVersion(datasetVersion: JsonField) = apply { this.datasetVersion = datasetVersion } + /** Date of experiment deletion, or null if the experiment is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + /** - * Whether or not the experiment is public. Public experiments can be viewed by anybody - * inside or outside the organization + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun public_(public_: Boolean) = public_(JsonField.of(public_)) + fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + + /** Textual description of the experiment */ + fun description(description: String?) = description(JsonField.ofNullable(description)) + + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) /** - * Whether or not the experiment is public. Public experiments can be viewed by anybody - * inside or outside the organization + * 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. */ - @JsonProperty("public") - @ExcludeMissing - fun public_(public_: JsonField) = apply { this.public_ = public_ } + fun description(description: JsonField) = apply { this.description = description } - /** Identifies the user who created the experiment */ - fun userId(userId: String) = userId(JsonField.of(userId)) + /** User-controlled metadata about the experiment */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** Metadata about the state of the repo when the experiment was created */ + fun repoInfo(repoInfo: RepoInfo?) = repoInfo(JsonField.ofNullable(repoInfo)) + + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) + + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun repoInfo(repoInfo: JsonField) = apply { this.repoInfo = repoInfo } /** Identifies the user who created the experiment */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - /** User-controlled metadata about the experiment */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Experiment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .public_() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Experiment = Experiment( - id, - projectId, - name, - description, - created, - repoInfo, - commit, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("public_", public_), baseExpId, - deletedAt, + commit, + created, datasetId, datasetVersion, - public_, - userId, + deletedAt, + description, metadata, - additionalProperties.toUnmodifiable(), + repoInfo, + userId, + additionalProperties.toImmutable(), ) } /** User-controlled metadata about the experiment */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Experiment && id == other.id && name == other.name && projectId == other.projectId && public_ == other.public_ && baseExpId == other.baseExpId && commit == other.commit && created == other.created && datasetId == other.datasetId && datasetVersion == other.datasetVersion && deletedAt == other.deletedAt && description == other.description && metadata == other.metadata && repoInfo == other.repoInfo && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, projectId, public_, baseExpId, commit, created, datasetId, datasetVersion, deletedAt, description, metadata, repoInfo, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Experiment{id=$id, name=$name, projectId=$projectId, public_=$public_, baseExpId=$baseExpId, commit=$commit, created=$created, datasetId=$datasetId, datasetVersion=$datasetVersion, deletedAt=$deletedAt, description=$description, metadata=$metadata, repoInfo=$repoInfo, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentCreateParams.kt index c4aa0d18..bee4ab93 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentCreateParams.kt @@ -3,288 +3,686 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new experiment. If there is an existing experiment in the project with the same name as + * the one specified in the request, will return the existing experiment unmodified + */ class ExperimentCreateParams -constructor( - private val projectId: String, - private val baseExpId: String?, - private val datasetId: String?, - private val datasetVersion: String?, - private val description: String?, - private val ensureNew: Boolean?, - private val metadata: Metadata?, - private val name: String?, - private val public_: Boolean?, - private val repoInfo: RepoInfo?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun projectId(): String = projectId - - fun baseExpId(): Optional = Optional.ofNullable(baseExpId) - - fun datasetId(): Optional = Optional.ofNullable(datasetId) - - fun datasetVersion(): Optional = Optional.ofNullable(datasetVersion) - - fun description(): Optional = Optional.ofNullable(description) - - fun ensureNew(): Optional = Optional.ofNullable(ensureNew) - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun name(): Optional = Optional.ofNullable(name) - - fun public_(): Optional = Optional.ofNullable(public_) - - fun repoInfo(): Optional = Optional.ofNullable(repoInfo) - - @JvmSynthetic - internal fun getBody(): ExperimentCreateBody { - return ExperimentCreateBody( - projectId, - baseExpId, - datasetId, - datasetVersion, - description, - ensureNew, - metadata, - name, - public_, - repoInfo, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Unique identifier for the project that the experiment belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Id of default base experiment to compare against when viewing this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baseExpId(): Optional = body.baseExpId() + + /** + * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun datasetId(): Optional = body.datasetId() + + /** + * Version number of the linked dataset the experiment was run against. This can be used to + * reproduce the experiment after the dataset has been modified. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun datasetVersion(): Optional = body.datasetVersion() + + /** + * Textual description of the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Normally, creating an experiment with the same name as an existing experiment will return the + * existing one un-modified. But if `ensure_new` is true, registration will generate a new + * experiment with a unique name in case of a conflict. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun ensureNew(): Optional = body.ensureNew() + + /** + * User-controlled metadata about the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * Name of the experiment. Within a project, experiment names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Whether or not the experiment is public. Public experiments can be viewed by anybody inside + * or outside the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun public_(): Optional = body.public_() + + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun repoInfo(): Optional = body.repoInfo() + + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [baseExpId]. + * + * Unlike [baseExpId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _baseExpId(): JsonField = body._baseExpId() + + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _datasetId(): JsonField = body._datasetId() + + /** + * Returns the raw JSON value of [datasetVersion]. + * + * Unlike [datasetVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _datasetVersion(): JsonField = body._datasetVersion() + + /** + * 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 [ensureNew]. + * + * Unlike [ensureNew], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _ensureNew(): JsonField = body._ensureNew() + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * 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 [public_]. + * + * Unlike [public_], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _public_(): JsonField = body._public_() + + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _repoInfo(): JsonField = body._repoInfo() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = ExperimentCreateBody.Builder::class) @NoAutoDetect - class ExperimentCreateBody - internal constructor( - private val projectId: String?, - private val baseExpId: String?, - private val datasetId: String?, - private val datasetVersion: String?, - private val description: String?, - private val ensureNew: Boolean?, - private val metadata: Metadata?, - private val name: String?, - private val public_: Boolean?, - private val repoInfo: RepoInfo?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("base_exp_id") + @ExcludeMissing + private val baseExpId: JsonField = JsonMissing.of(), + @JsonProperty("dataset_id") + @ExcludeMissing + private val datasetId: JsonField = JsonMissing.of(), + @JsonProperty("dataset_version") + @ExcludeMissing + private val datasetVersion: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("ensure_new") + @ExcludeMissing + private val ensureNew: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("public") + @ExcludeMissing + private val public_: JsonField = JsonMissing.of(), + @JsonProperty("repo_info") + @ExcludeMissing + private val repoInfo: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId + /** + * Unique identifier for the project that the experiment belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") fun baseExpId(): String? = baseExpId + /** + * Id of default base experiment to compare against when viewing this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun baseExpId(): Optional = + Optional.ofNullable(baseExpId.getNullable("base_exp_id")) /** * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("dataset_id") fun datasetId(): String? = datasetId + fun datasetId(): Optional = Optional.ofNullable(datasetId.getNullable("dataset_id")) /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("dataset_version") fun datasetVersion(): String? = datasetVersion + fun datasetVersion(): Optional = + Optional.ofNullable(datasetVersion.getNullable("dataset_version")) - /** Textual description of the experiment */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) /** * Normally, creating an experiment with the same name as an existing experiment will return * the existing one un-modified. But if `ensure_new` is true, registration will generate a * new experiment with a unique name in case of a conflict. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("ensure_new") fun ensureNew(): Boolean? = ensureNew + fun ensureNew(): Optional = + Optional.ofNullable(ensureNew.getNullable("ensure_new")) - /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") fun metadata(): Metadata? = metadata + /** + * User-controlled metadata about the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the experiment. Within a project, experiment names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("public") fun public_(): Boolean? = public_ + fun public_(): Optional = Optional.ofNullable(public_.getNullable("public")) - /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") fun repoInfo(): RepoInfo? = repoInfo + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun repoInfo(): Optional = Optional.ofNullable(repoInfo.getNullable("repo_info")) + + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [baseExpId]. + * + * Unlike [baseExpId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("base_exp_id") @ExcludeMissing fun _baseExpId(): JsonField = baseExpId + + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId(): JsonField = datasetId + + /** + * Returns the raw JSON value of [datasetVersion]. + * + * Unlike [datasetVersion], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("dataset_version") + @ExcludeMissing + fun _datasetVersion(): JsonField = datasetVersion + + /** + * 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 [ensureNew]. + * + * Unlike [ensureNew], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ensure_new") @ExcludeMissing fun _ensureNew(): JsonField = ensureNew + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * 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 [public_]. + * + * Unlike [public_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("public") @ExcludeMissing fun _public_(): JsonField = public_ + + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("repo_info") @ExcludeMissing fun _repoInfo(): JsonField = repoInfo @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ExperimentCreateBody && - this.projectId == other.projectId && - this.baseExpId == other.baseExpId && - this.datasetId == other.datasetId && - this.datasetVersion == other.datasetVersion && - this.description == other.description && - this.ensureNew == other.ensureNew && - this.metadata == other.metadata && - this.name == other.name && - this.public_ == other.public_ && - this.repoInfo == other.repoInfo && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectId, - baseExpId, - datasetId, - datasetVersion, - description, - ensureNew, - metadata, - name, - public_, - repoInfo, - additionalProperties, - ) - } - return hashCode + projectId() + baseExpId() + datasetId() + datasetVersion() + description() + ensureNew() + metadata().ifPresent { it.validate() } + name() + public_() + repoInfo().ifPresent { it.validate() } + validated = true } - override fun toString() = - "ExperimentCreateBody{projectId=$projectId, baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, ensureNew=$ensureNew, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var projectId: String? = null - private var baseExpId: String? = null - private var datasetId: String? = null - private var datasetVersion: String? = null - private var description: String? = null - private var ensureNew: Boolean? = null - private var metadata: Metadata? = null - private var name: String? = null - private var public_: Boolean? = null - private var repoInfo: RepoInfo? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var projectId: JsonField? = null + private var baseExpId: JsonField = JsonMissing.of() + private var datasetId: JsonField = JsonMissing.of() + private var datasetVersion: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var ensureNew: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var public_: JsonField = JsonMissing.of() + private var repoInfo: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(experimentCreateBody: ExperimentCreateBody) = apply { - this.projectId = experimentCreateBody.projectId - this.baseExpId = experimentCreateBody.baseExpId - this.datasetId = experimentCreateBody.datasetId - this.datasetVersion = experimentCreateBody.datasetVersion - this.description = experimentCreateBody.description - this.ensureNew = experimentCreateBody.ensureNew - this.metadata = experimentCreateBody.metadata - this.name = experimentCreateBody.name - this.public_ = experimentCreateBody.public_ - this.repoInfo = experimentCreateBody.repoInfo - additionalProperties(experimentCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + projectId = body.projectId + baseExpId = body.baseExpId + datasetId = body.datasetId + datasetVersion = body.datasetVersion + description = body.description + ensureNew = body.ensureNew + metadata = body.metadata + name = body.name + public_ = body.public_ + repoInfo = body.repoInfo + additionalProperties = body.additionalProperties.toMutableMap() } /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") - fun baseExpId(baseExpId: String) = apply { this.baseExpId = baseExpId } + fun baseExpId(baseExpId: String?) = baseExpId(JsonField.ofNullable(baseExpId)) + + /** Alias for calling [Builder.baseExpId] with `baseExpId.orElse(null)`. */ + fun baseExpId(baseExpId: Optional) = baseExpId(baseExpId.getOrNull()) + + /** + * Sets [Builder.baseExpId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExpId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExpId(baseExpId: JsonField) = apply { this.baseExpId = baseExpId } /** * Identifier of the linked dataset, or null if the experiment is not linked to a * dataset */ - @JsonProperty("dataset_id") - fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } + fun datasetId(datasetId: String?) = datasetId(JsonField.ofNullable(datasetId)) + + /** Alias for calling [Builder.datasetId] with `datasetId.orElse(null)`. */ + fun datasetId(datasetId: Optional) = datasetId(datasetId.getOrNull()) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } /** * Version number of the linked dataset the experiment was run against. This can be used * to reproduce the experiment after the dataset has been modified. */ - @JsonProperty("dataset_version") - fun datasetVersion(datasetVersion: String) = apply { + fun datasetVersion(datasetVersion: String?) = + datasetVersion(JsonField.ofNullable(datasetVersion)) + + /** Alias for calling [Builder.datasetVersion] with `datasetVersion.orElse(null)`. */ + fun datasetVersion(datasetVersion: Optional) = + datasetVersion(datasetVersion.getOrNull()) + + /** + * Sets [Builder.datasetVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetVersion(datasetVersion: JsonField) = apply { this.datasetVersion = datasetVersion } /** Textual description of the experiment */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** * Normally, creating an experiment with the same name as an existing experiment will * return the existing one un-modified. But if `ensure_new` is true, registration will * generate a new experiment with a unique name in case of a conflict. */ - @JsonProperty("ensure_new") - fun ensureNew(ensureNew: Boolean) = apply { this.ensureNew = ensureNew } + fun ensureNew(ensureNew: Boolean?) = ensureNew(JsonField.ofNullable(ensureNew)) + + /** + * Alias for [Builder.ensureNew]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun ensureNew(ensureNew: Boolean) = ensureNew(ensureNew as Boolean?) + + /** Alias for calling [Builder.ensureNew] with `ensureNew.orElse(null)`. */ + fun ensureNew(ensureNew: Optional) = ensureNew(ensureNew.getOrNull()) + + /** + * Sets [Builder.ensureNew] to an arbitrary JSON value. + * + * You should usually call [Builder.ensureNew] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ensureNew(ensureNew: JsonField) = apply { this.ensureNew = ensureNew } /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization */ - @JsonProperty("public") fun public_(public_: Boolean) = apply { this.public_ = public_ } + fun public_(public_: Boolean?) = public_(JsonField.ofNullable(public_)) + + /** + * Alias for [Builder.public_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun public_(public_: Boolean) = public_(public_ as Boolean?) + + /** Alias for calling [Builder.public_] with `public_.orElse(null)`. */ + fun public_(public_: Optional) = public_(public_.getOrNull()) + + /** + * Sets [Builder.public_] to an arbitrary JSON value. + * + * You should usually call [Builder.public_] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun public_(public_: JsonField) = apply { this.public_ = public_ } /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") - fun repoInfo(repoInfo: RepoInfo) = apply { this.repoInfo = repoInfo } + fun repoInfo(repoInfo: RepoInfo?) = repoInfo(JsonField.ofNullable(repoInfo)) + + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) + + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun repoInfo(repoInfo: JsonField) = apply { this.repoInfo = repoInfo } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ExperimentCreateBody = - ExperimentCreateBody( - checkNotNull(projectId) { "`projectId` is required but was not set" }, + 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 + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("projectId", projectId), baseExpId, datasetId, datasetVersion, @@ -294,276 +692,464 @@ constructor( name, public_, repoInfo, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && projectId == other.projectId && baseExpId == other.baseExpId && datasetId == other.datasetId && datasetVersion == other.datasetVersion && description == other.description && ensureNew == other.ensureNew && metadata == other.metadata && name == other.name && public_ == other.public_ && repoInfo == other.repoInfo && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ExperimentCreateParams && - this.projectId == other.projectId && - this.baseExpId == other.baseExpId && - this.datasetId == other.datasetId && - this.datasetVersion == other.datasetVersion && - this.description == other.description && - this.ensureNew == other.ensureNew && - this.metadata == other.metadata && - this.name == other.name && - this.public_ == other.public_ && - this.repoInfo == other.repoInfo && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(projectId, baseExpId, datasetId, datasetVersion, description, ensureNew, metadata, name, public_, repoInfo, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectId, - baseExpId, - datasetId, - datasetVersion, - description, - ensureNew, - metadata, - name, - public_, - repoInfo, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ExperimentCreateParams{projectId=$projectId, baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, ensureNew=$ensureNew, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{projectId=$projectId, baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, ensureNew=$ensureNew, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentCreateParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentCreateParams]. */ @NoAutoDetect - class Builder { - - private var projectId: String? = null - private var baseExpId: String? = null - private var datasetId: String? = null - private var datasetVersion: String? = null - private var description: String? = null - private var ensureNew: Boolean? = null - private var metadata: Metadata? = null - private var name: String? = null - private var public_: Boolean? = null - private var repoInfo: RepoInfo? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(experimentCreateParams: ExperimentCreateParams) = apply { - this.projectId = experimentCreateParams.projectId - this.baseExpId = experimentCreateParams.baseExpId - this.datasetId = experimentCreateParams.datasetId - this.datasetVersion = experimentCreateParams.datasetVersion - this.description = experimentCreateParams.description - this.ensureNew = experimentCreateParams.ensureNew - this.metadata = experimentCreateParams.metadata - this.name = experimentCreateParams.name - this.public_ = experimentCreateParams.public_ - this.repoInfo = experimentCreateParams.repoInfo - additionalQueryParams(experimentCreateParams.additionalQueryParams) - additionalHeaders(experimentCreateParams.additionalHeaders) - additionalBodyProperties(experimentCreateParams.additionalBodyProperties) + body = experimentCreateParams.body.toBuilder() + additionalHeaders = experimentCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentCreateParams.additionalQueryParams.toBuilder() } /** Unique identifier for the project that the experiment belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Id of default base experiment to compare against when viewing this experiment */ - fun baseExpId(baseExpId: String) = apply { this.baseExpId = baseExpId } + fun baseExpId(baseExpId: String?) = apply { body.baseExpId(baseExpId) } + + /** Alias for calling [Builder.baseExpId] with `baseExpId.orElse(null)`. */ + fun baseExpId(baseExpId: Optional) = baseExpId(baseExpId.getOrNull()) + + /** + * Sets [Builder.baseExpId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExpId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun baseExpId(baseExpId: JsonField) = apply { body.baseExpId(baseExpId) } /** * Identifier of the linked dataset, or null if the experiment is not linked to a dataset */ - fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } + fun datasetId(datasetId: String?) = apply { body.datasetId(datasetId) } + + /** Alias for calling [Builder.datasetId] with `datasetId.orElse(null)`. */ + fun datasetId(datasetId: Optional) = datasetId(datasetId.getOrNull()) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun datasetId(datasetId: JsonField) = apply { body.datasetId(datasetId) } /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. */ - fun datasetVersion(datasetVersion: String) = apply { this.datasetVersion = datasetVersion } + fun datasetVersion(datasetVersion: String?) = apply { body.datasetVersion(datasetVersion) } + + /** Alias for calling [Builder.datasetVersion] with `datasetVersion.orElse(null)`. */ + fun datasetVersion(datasetVersion: Optional) = + datasetVersion(datasetVersion.getOrNull()) + + /** + * Sets [Builder.datasetVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetVersion(datasetVersion: JsonField) = apply { + body.datasetVersion(datasetVersion) + } /** Textual description of the experiment */ - fun description(description: String) = apply { this.description = description } + 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) } /** * Normally, creating an experiment with the same name as an existing experiment will return * the existing one un-modified. But if `ensure_new` is true, registration will generate a * new experiment with a unique name in case of a conflict. */ - fun ensureNew(ensureNew: Boolean) = apply { this.ensureNew = ensureNew } + fun ensureNew(ensureNew: Boolean?) = apply { body.ensureNew(ensureNew) } + + /** + * Alias for [Builder.ensureNew]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun ensureNew(ensureNew: Boolean) = ensureNew(ensureNew as Boolean?) + + /** Alias for calling [Builder.ensureNew] with `ensureNew.orElse(null)`. */ + fun ensureNew(ensureNew: Optional) = ensureNew(ensureNew.getOrNull()) + + /** + * Sets [Builder.ensureNew] to an arbitrary JSON value. + * + * You should usually call [Builder.ensureNew] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ensureNew(ensureNew: JsonField) = apply { body.ensureNew(ensureNew) } /** User-controlled metadata about the experiment */ - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** Name of the experiment. Within a project, experiment names are unique */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization */ - fun public_(public_: Boolean) = apply { this.public_ = public_ } + fun public_(public_: Boolean?) = apply { body.public_(public_) } + + /** + * Alias for [Builder.public_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun public_(public_: Boolean) = public_(public_ as Boolean?) + + /** Alias for calling [Builder.public_] with `public_.orElse(null)`. */ + fun public_(public_: Optional) = public_(public_.getOrNull()) + + /** + * Sets [Builder.public_] to an arbitrary JSON value. + * + * You should usually call [Builder.public_] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun public_(public_: JsonField) = apply { body.public_(public_) } /** Metadata about the state of the repo when the experiment was created */ - fun repoInfo(repoInfo: RepoInfo) = apply { this.repoInfo = repoInfo } + fun repoInfo(repoInfo: RepoInfo?) = apply { body.repoInfo(repoInfo) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun repoInfo(repoInfo: JsonField) = apply { body.repoInfo(repoInfo) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ExperimentCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentCreateParams = ExperimentCreateParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - baseExpId, - datasetId, - datasetVersion, - description, - ensureNew, - metadata, - name, - public_, - repoInfo, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } /** User-controlled metadata about the experiment */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentDeleteParams.kt index e3e57b22..78bec198 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an experiment object by its id */ class ExperimentDeleteParams -constructor( +private constructor( private val experimentId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,147 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExperimentDeleteParams && - this.experimentId == other.experimentId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - experimentId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "ExperimentDeleteParams{experimentId=$experimentId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentDeleteParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(experimentDeleteParams: ExperimentDeleteParams) = apply { - this.experimentId = experimentDeleteParams.experimentId - additionalQueryParams(experimentDeleteParams.additionalQueryParams) - additionalHeaders(experimentDeleteParams.additionalHeaders) - additionalBodyProperties(experimentDeleteParams.additionalBodyProperties) + experimentId = experimentDeleteParams.experimentId + additionalHeaders = experimentDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + experimentDeleteParams.additionalBodyProperties.toMutableMap() } /** Experiment id */ fun experimentId(experimentId: String) = apply { this.experimentId = experimentId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +193,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [ExperimentDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentDeleteParams = ExperimentDeleteParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("experimentId", experimentId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentDeleteParams && experimentId == other.experimentId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "ExperimentDeleteParams{experimentId=$experimentId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentEvent.kt index ec5c09a6..aa0f500c 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentEvent.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentEvent.kt @@ -2,98 +2,155 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ExperimentEvent.Builder::class) @NoAutoDetect class ExperimentEvent +@JsonCreator private constructor( - private val id: JsonField, - private val datasetRecordId: JsonField, - private val _xactId: JsonField, - private val created: JsonField, - private val projectId: JsonField, - private val experimentId: JsonField, - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanId: JsonField, - private val spanParents: JsonField>, - private val rootSpanId: JsonField, - private val spanAttributes: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("experiment_id") + @ExcludeMissing + private val experimentId: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + private val context: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing private val error: JsonValue = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("is_root") + @ExcludeMissing + private val isRoot: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("metrics") + @ExcludeMissing + private val metrics: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("output") @ExcludeMissing private val output: JsonValue = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("span_attributes") + @ExcludeMissing + private val spanAttributes: JsonField = JsonMissing.of(), + @JsonProperty("span_parents") + @ExcludeMissing + private val spanParents: JsonField> = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * A unique identifier for the experiment event. If you don't provide one, BrainTrust will * generate one for you + * + * @throws BraintrustInvalidDataException 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") - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - fun datasetRecordId(): Optional = - Optional.ofNullable(datasetRecordId.getNullable("dataset_record_id")) - /** * The transaction id of an event is unique to the network operation that processed the event * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve * a versioned snapshot of the experiment (see the `version` parameter) + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") - /** The timestamp the experiment event was created */ + /** + * The timestamp the experiment event was created + * + * @throws BraintrustInvalidDataException 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 created(): OffsetDateTime = created.getRequired("created") - /** Unique identifier for the project that the experiment belongs under */ + /** + * Unique identifier for the experiment + * + * @throws BraintrustInvalidDataException 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 experimentId(): String = experimentId.getRequired("experiment_id") + + /** + * Unique identifier for the project that the experiment belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the experiment */ - fun experimentId(): String = experimentId.getRequired("experiment_id") + /** + * A unique identifier for the trace this experiment event belongs to + * + * @throws BraintrustInvalidDataException 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 rootSpanId(): String = rootSpanId.getRequired("root_span_id") /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical + * A unique identifier used to link different experiment events together as part of a full + * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full + * details on tracing + * + * @throws BraintrustInvalidDataException 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 input(): JsonValue = input + fun spanId(): String = spanId.getRequired("span_id") /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question + * Context is additional information about the code that produced the experiment event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun output(): JsonValue = output + fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + + /** The error that occurred, if any. */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonValue = error /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to @@ -103,21 +160,23 @@ private constructor( * digging into analyses. However, we may later use these values to re-score outputs or * fine-tune your models */ - fun expected(): JsonValue = expected + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected - /** The error that occurred, if any. */ - fun error(): JsonValue = error + /** + * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). + * Later on, Braintrust will use the `input` to know whether two test cases are the same between + * experiments, so they should not contain experiment-specific state. A simple rule of thumb is + * that if you run the same experiment twice, the `input` should be identical + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments + * Whether this span is a root span + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + fun isRoot(): Optional = Optional.ofNullable(isRoot.getNullable("is_root")) /** * A dictionary with additional data about the test example, model outputs, or just about @@ -125,302 +184,297 @@ private constructor( * example, you could log the `prompt`, example's `id`, or anything else that would be useful to * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** * Metrics are numerical measurements tracking the execution of the code that produced the * experiment event. Use "start" and "end" to track the time span over which the experiment * event was produced + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) /** - * A unique identifier used to link different experiment events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * The output of your application, including post-processing (an arbitrary, JSON serializable + * object), that allows you to determine whether the result is correct or not. For example, in + * an app that generates SQL queries, the `output` should be the _result_ of the SQL query + * generated by the model, not the query itself, because there may be multiple valid queries + * that answer a single question */ - fun spanId(): String = spanId.getRequired("span_id") + @JsonProperty("output") @ExcludeMissing fun _output(): JsonValue = output /** - * An array of the parent `span_ids` of this experiment event. This should be empty for the root - * span of a trace, and should most often contain just one parent element for subspans + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare experiments + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun spanParents(): Optional> = - Optional.ofNullable(spanParents.getNullable("span_parents")) - - /** The `span_id` of the root of the trace this experiment event belongs to */ - fun rootSpanId(): String = rootSpanId.getRequired("root_span_id") + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - /** Human-identifying attributes of the span, such as name, type, etc. */ + /** + * Human-identifying attributes of the span, such as name, type, etc. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun spanAttributes(): Optional = Optional.ofNullable(spanAttributes.getNullable("span_attributes")) /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you + * An array of the parent `span_ids` of this experiment event. This should be empty for the root + * span of a trace, and should most often contain just one parent element for subspans + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + fun spanParents(): Optional> = + Optional.ofNullable(spanParents.getNullable("span_parents")) /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("dataset_record_id") @ExcludeMissing fun _datasetRecordId() = datasetRecordId + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) /** - * The transaction id of an event is unique to the network operation that processed the event - * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve - * a versioned snapshot of the experiment (see the `version` parameter) + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("_xact_id") @ExcludeMissing fun __xactId() = _xactId + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id - /** The timestamp the experiment event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Returns the raw JSON value of [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId - /** Unique identifier for the experiment */ - @JsonProperty("experiment_id") @ExcludeMissing fun _experimentId() = experimentId + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical + * Returns the raw JSON value of [experimentId]. + * + * Unlike [experimentId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("input") @ExcludeMissing fun _input() = input + @JsonProperty("experiment_id") + @ExcludeMissing + fun _experimentId(): JsonField = experimentId /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("output") @ExcludeMissing fun _output() = output + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate your experiments while - * digging into analyses. However, we may later use these values to re-score outputs or - * fine-tune your models + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings + * Returns the raw JSON value of [isRoot]. + * + * Unlike [isRoot], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("is_root") @ExcludeMissing fun _isRoot(): JsonField = isRoot - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced + * Returns the raw JSON value of [metrics]. + * + * Unlike [metrics], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics + @JsonProperty("metrics") @ExcludeMissing fun _metrics(): JsonField = metrics /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("context") @ExcludeMissing fun _context() = context + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin /** - * A unique identifier used to link different experiment events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("span_id") @ExcludeMissing fun _spanId() = spanId + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores /** - * An array of the parent `span_ids` of this experiment event. This should be empty for the root - * span of a trace, and should most often contain just one parent element for subspans + * Returns the raw JSON value of [spanAttributes]. + * + * Unlike [spanAttributes], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("span_parents") @ExcludeMissing fun _spanParents() = spanParents + @JsonProperty("span_attributes") + @ExcludeMissing + fun _spanAttributes(): JsonField = spanAttributes - /** The `span_id` of the root of the trace this experiment event belongs to */ - @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId() = rootSpanId + /** + * Returns the raw JSON value of [spanParents]. + * + * Unlike [spanParents], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_parents") + @ExcludeMissing + fun _spanParents(): JsonField> = spanParents - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ExperimentEvent = apply { - if (!validated) { - id() - datasetRecordId() - _xactId() - created() - projectId() - experimentId() - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanId() - spanParents() - rootSpanId() - spanAttributes().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ExperimentEvent = apply { + if (validated) { + return@apply } - return other is ExperimentEvent && - this.id == other.id && - this.datasetRecordId == other.datasetRecordId && - this._xactId == other._xactId && - this.created == other.created && - this.projectId == other.projectId && - this.experimentId == other.experimentId && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanId == other.spanId && - this.spanParents == other.spanParents && - this.rootSpanId == other.rootSpanId && - this.spanAttributes == other.spanAttributes && - this.additionalProperties == other.additionalProperties + id() + _xactId() + created() + experimentId() + projectId() + rootSpanId() + spanId() + context().ifPresent { it.validate() } + isRoot() + metadata().ifPresent { it.validate() } + metrics().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + scores().ifPresent { it.validate() } + spanAttributes().ifPresent { it.validate() } + spanParents() + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - datasetRecordId, - _xactId, - created, - projectId, - experimentId, - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanId, - spanParents, - rootSpanId, - spanAttributes, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ExperimentEvent{id=$id, datasetRecordId=$datasetRecordId, _xactId=$_xactId, created=$created, projectId=$projectId, experimentId=$experimentId, input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanId=$spanId, spanParents=$spanParents, rootSpanId=$rootSpanId, spanAttributes=$spanAttributes, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentEvent]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .experimentId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ExperimentEvent]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var datasetRecordId: JsonField = JsonMissing.of() - private var _xactId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var experimentId: JsonField = JsonMissing.of() - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var created: JsonField? = null + private var experimentId: JsonField? = null + private var projectId: JsonField? = null + private var rootSpanId: JsonField? = null + private var spanId: JsonField? = null + private var context: JsonField = JsonMissing.of() private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var isRoot: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanId: JsonField = JsonMissing.of() - private var spanParents: JsonField> = JsonMissing.of() - private var rootSpanId: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var output: JsonValue = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() private var spanAttributes: JsonField = JsonMissing.of() + private var spanParents: JsonField>? = null + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(experimentEvent: ExperimentEvent) = apply { - this.id = experimentEvent.id - this.datasetRecordId = experimentEvent.datasetRecordId - this._xactId = experimentEvent._xactId - this.created = experimentEvent.created - this.projectId = experimentEvent.projectId - this.experimentId = experimentEvent.experimentId - this.input = experimentEvent.input - this.output = experimentEvent.output - this.expected = experimentEvent.expected - this.error = experimentEvent.error - this.scores = experimentEvent.scores - this.metadata = experimentEvent.metadata - this.tags = experimentEvent.tags - this.metrics = experimentEvent.metrics - this.context = experimentEvent.context - this.spanId = experimentEvent.spanId - this.spanParents = experimentEvent.spanParents - this.rootSpanId = experimentEvent.rootSpanId - this.spanAttributes = experimentEvent.spanAttributes - additionalProperties(experimentEvent.additionalProperties) + id = experimentEvent.id + _xactId = experimentEvent._xactId + created = experimentEvent.created + experimentId = experimentEvent.experimentId + projectId = experimentEvent.projectId + rootSpanId = experimentEvent.rootSpanId + spanId = experimentEvent.spanId + context = experimentEvent.context + error = experimentEvent.error + expected = experimentEvent.expected + input = experimentEvent.input + isRoot = experimentEvent.isRoot + metadata = experimentEvent.metadata + metrics = experimentEvent.metrics + origin = experimentEvent.origin + output = experimentEvent.output + scores = experimentEvent.scores + spanAttributes = experimentEvent.spanAttributes + spanParents = experimentEvent.spanParents.map { it.toMutableList() } + tags = experimentEvent.tags.map { it.toMutableList() } + additionalProperties = experimentEvent.additionalProperties.toMutableMap() } /** @@ -430,27 +484,12 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to + * 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 datasetRecordId(datasetRecordId: String) = - datasetRecordId(JsonField.of(datasetRecordId)) - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - @JsonProperty("dataset_record_id") - @ExcludeMissing - fun datasetRecordId(datasetRecordId: JsonField) = apply { - this.datasetRecordId = datasetRecordId - } + fun id(id: JsonField) = apply { this.id = id } /** * The transaction id of an event is unique to the network operation that processed the @@ -460,60 +499,98 @@ private constructor( fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) /** - * The transaction id of an event is unique to the network operation that processed the - * event insertion. Transaction ids are monotonically increasing over time and can be used - * to retrieve a versioned snapshot of the experiment (see the `version` parameter) + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("_xact_id") - @ExcludeMissing fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } /** The timestamp the experiment event was created */ fun created(created: OffsetDateTime) = created(JsonField.of(created)) - /** The timestamp the experiment event was created */ - @JsonProperty("created") - @ExcludeMissing + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } - /** Unique identifier for the project that the experiment belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - - /** Unique identifier for the project that the experiment belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - /** Unique identifier for the experiment */ fun experimentId(experimentId: String) = experimentId(JsonField.of(experimentId)) - /** Unique identifier for the experiment */ - @JsonProperty("experiment_id") - @ExcludeMissing + /** + * Sets [Builder.experimentId] to an arbitrary JSON value. + * + * You should usually call [Builder.experimentId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun experimentId(experimentId: JsonField) = apply { this.experimentId = experimentId } + /** Unique identifier for the project that the experiment belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same - * between experiments, so they should not contain experiment-specific state. A simple rule - * of thumb is that if you run the same experiment twice, the `input` should be identical + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + + /** A unique identifier for the trace this experiment event belongs to */ + fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + + /** + * A unique identifier used to link different experiment events together as part of a full + * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full + * details on tracing + */ + fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + + /** + * Context is additional information about the code that produced the experiment event. It + * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to + * track the location in code which produced the experiment event + */ + fun context(context: Context?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [Context] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + /** The error that occurred, if any. */ + fun error(error: JsonValue) = apply { this.error = error } /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to @@ -523,38 +600,36 @@ private constructor( * while digging into analyses. However, we may later use these values to re-score outputs * or fine-tune your models */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } + fun expected(expected: JsonValue) = apply { this.expected = expected } + + /** + * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). + * Later on, Braintrust will use the `input` to know whether two test cases are the same + * between experiments, so they should not contain experiment-specific state. A simple rule + * of thumb is that if you run the same experiment twice, the `input` should be identical + */ + fun input(input: JsonValue) = apply { this.input = input } - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } + /** Whether this span is a root span */ + fun isRoot(isRoot: Boolean?) = isRoot(JsonField.ofNullable(isRoot)) /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments + * Alias for [Builder.isRoot]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) + fun isRoot(isRoot: Boolean) = isRoot(isRoot as Boolean?) + + /** Alias for calling [Builder.isRoot] with `isRoot.orElse(null)`. */ + fun isRoot(isRoot: Optional) = isRoot(isRoot.getOrNull()) /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments + * Sets [Builder.isRoot] to an arbitrary JSON value. + * + * You should usually call [Builder.isRoot] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } + fun isRoot(isRoot: JsonField) = apply { this.isRoot = isRoot } /** * A dictionary with additional data about the test example, model outputs, or just about @@ -563,146 +638,221 @@ private constructor( * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, * but its keys must be strings */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("metadata") - @ExcludeMissing fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - /** * Metrics are numerical measurements tracking the execution of the code that produced the * experiment event. Use "start" and "end" to track the time span over which the experiment * event was produced */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) + fun metrics(metrics: Metrics?) = metrics(JsonField.ofNullable(metrics)) + + /** Alias for calling [Builder.metrics] with `metrics.orElse(null)`. */ + fun metrics(metrics: Optional) = metrics(metrics.getOrNull()) /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced + * Sets [Builder.metrics] to an arbitrary JSON value. + * + * You should usually call [Builder.metrics] with a well-typed [Metrics] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("metrics") - @ExcludeMissing fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun context(context: Context) = context(JsonField.of(context)) + fun origin(origin: JsonField) = apply { this.origin = origin } /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event + * The output of your application, including post-processing (an arbitrary, JSON + * serializable object), that allows you to determine whether the result is correct or not. + * For example, in an app that generates SQL queries, the `output` should be the _result_ of + * the SQL query generated by the model, not the query itself, because there may be multiple + * valid queries that answer a single question */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } + fun output(output: JsonValue) = apply { this.output = output } /** - * A unique identifier used to link different experiment events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a + * variety of signals that help you determine how accurate the outputs are compared to what + * you expect and diagnose failures. For example, a summarization app might have one score + * that tells you how accurate the summary is, and another that measures the word similarity + * between the generated and grouth truth summary. The word similarity score could help you + * determine whether the summarization was covering similar concepts or not. You can use + * these scores to help you sort, filter, and compare experiments */ - fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) /** - * A unique identifier used to link different experiment events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("span_id") - @ExcludeMissing - fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + fun scores(scores: JsonField) = apply { this.scores = scores } + + /** Human-identifying attributes of the span, such as name, type, etc. */ + fun spanAttributes(spanAttributes: SpanAttributes?) = + spanAttributes(JsonField.ofNullable(spanAttributes)) + + /** Alias for calling [Builder.spanAttributes] with `spanAttributes.orElse(null)`. */ + fun spanAttributes(spanAttributes: Optional) = + spanAttributes(spanAttributes.getOrNull()) /** - * An array of the parent `span_ids` of this experiment event. This should be empty for the - * root span of a trace, and should most often contain just one parent element for subspans + * Sets [Builder.spanAttributes] to an arbitrary JSON value. + * + * You should usually call [Builder.spanAttributes] with a well-typed [SpanAttributes] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun spanParents(spanParents: List) = spanParents(JsonField.of(spanParents)) + fun spanAttributes(spanAttributes: JsonField) = apply { + this.spanAttributes = spanAttributes + } /** * An array of the parent `span_ids` of this experiment event. This should be empty for the * root span of a trace, and should most often contain just one parent element for subspans */ - @JsonProperty("span_parents") - @ExcludeMissing + fun spanParents(spanParents: List?) = spanParents(JsonField.ofNullable(spanParents)) + + /** Alias for calling [Builder.spanParents] with `spanParents.orElse(null)`. */ + fun spanParents(spanParents: Optional>) = spanParents(spanParents.getOrNull()) + + /** + * Sets [Builder.spanParents] to an arbitrary JSON value. + * + * You should usually call [Builder.spanParents] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun spanParents(spanParents: JsonField>) = apply { - this.spanParents = spanParents + this.spanParents = spanParents.map { it.toMutableList() } } - /** The `span_id` of the root of the trace this experiment event belongs to */ - fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) + /** + * Adds a single [String] to [spanParents]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanParent(spanParent: String) = apply { + spanParents = + (spanParents ?: JsonField.of(mutableListOf())).also { + checkKnown("spanParents", it).add(spanParent) + } + } - /** The `span_id` of the root of the trace this experiment event belongs to */ - @JsonProperty("root_span_id") - @ExcludeMissing - fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ExperimentEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .experimentId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentEvent = ExperimentEvent( - id, - datasetRecordId, - _xactId, - created, - projectId, - experimentId, - input, - output, - expected, + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("created", created), + checkRequired("experimentId", experimentId), + checkRequired("projectId", projectId), + checkRequired("rootSpanId", rootSpanId), + checkRequired("spanId", spanId), + context, error, - scores, + expected, + input, + isRoot, metadata, - tags.map { it.toUnmodifiable() }, metrics, - context, - spanId, - spanParents.map { it.toUnmodifiable() }, - rootSpanId, + origin, + output, + scores, spanAttributes, - additionalProperties.toUnmodifiable(), + (spanParents ?: JsonMissing.of()).map { it.toImmutable() }, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } @@ -711,160 +861,235 @@ private constructor( * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the * location in code which produced the experiment event */ - @JsonDeserialize(builder = Context.Builder::class) @NoAutoDetect class Context + @JsonCreator private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonField = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonField = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * Name of the file in code where the experiment event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFilename(): Optional = + Optional.ofNullable(callerFilename.getNullable("caller_filename")) - /** The function in code which created the experiment event */ + /** + * The function in code which created the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun callerFunctionname(): Optional = Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - /** Name of the file in code where the experiment event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the experiment event was created */ + /** + * Line of code where the experiment event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun callerLineno(): Optional = Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") + /** + * Returns the raw JSON value of [callerFilename]. + * + * Unlike [callerFilename], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_filename") @ExcludeMissing - fun _callerFunctionname() = callerFunctionname + fun _callerFilename(): JsonField = callerFilename - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename + /** + * Returns the raw JSON value of [callerFunctionname]. + * + * Unlike [callerFunctionname], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonField = callerFunctionname - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno + /** + * Returns the raw JSON value of [callerLineno]. + * + * Unlike [callerLineno], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_lineno") + @ExcludeMissing + fun _callerLineno(): JsonField = callerLineno @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Context = apply { + if (validated) { + return@apply } - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode + callerFilename() + callerFunctionname() + callerLineno() + validated = true } - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Context]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Context]. */ + class Builder internal constructor() { - private var callerFunctionname: JsonField = JsonMissing.of() private var callerFilename: JsonField = JsonMissing.of() + private var callerFunctionname: JsonField = JsonMissing.of() private var callerLineno: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) + callerFilename = context.callerFilename + callerFunctionname = context.callerFunctionname + callerLineno = context.callerLineno + additionalProperties = context.additionalProperties.toMutableMap() } - /** The function in code which created the experiment event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) + /** Name of the file in code where the experiment event was created */ + fun callerFilename(callerFilename: String?) = + callerFilename(JsonField.ofNullable(callerFilename)) + + /** Alias for calling [Builder.callerFilename] with `callerFilename.orElse(null)`. */ + fun callerFilename(callerFilename: Optional) = + callerFilename(callerFilename.getOrNull()) + + /** + * Sets [Builder.callerFilename] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFilename] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFilename(callerFilename: JsonField) = apply { + this.callerFilename = callerFilename + } /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") - @ExcludeMissing + fun callerFunctionname(callerFunctionname: String?) = + callerFunctionname(JsonField.ofNullable(callerFunctionname)) + + /** + * Alias for calling [Builder.callerFunctionname] with + * `callerFunctionname.orElse(null)`. + */ + fun callerFunctionname(callerFunctionname: Optional) = + callerFunctionname(callerFunctionname.getOrNull()) + + /** + * Sets [Builder.callerFunctionname] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFunctionname] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun callerFunctionname(callerFunctionname: JsonField) = apply { this.callerFunctionname = callerFunctionname } - /** Name of the file in code where the experiment event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) + /** Line of code where the experiment event was created */ + fun callerLineno(callerLineno: Long?) = callerLineno(JsonField.ofNullable(callerLineno)) - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } + /** + * Alias for [Builder.callerLineno]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun callerLineno(callerLineno: Long) = callerLineno(callerLineno as Long?) - /** Line of code where the experiment event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) + /** Alias for calling [Builder.callerLineno] with `callerLineno.orElse(null)`. */ + fun callerLineno(callerLineno: Optional) = callerLineno(callerLineno.getOrNull()) - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing + /** + * Sets [Builder.callerLineno] to an arbitrary JSON value. + * + * You should usually call [Builder.callerLineno] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun callerLineno(callerLineno: JsonField) = apply { this.callerLineno = callerLineno } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Context]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): Context = Context( - callerFunctionname, callerFilename, + callerFunctionname, callerLineno, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Context && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Context{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" } /** @@ -874,76 +1099,125 @@ private constructor( * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) - private var hashCode: Int = 0 + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + model() + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { + private var model: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() } + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" } /** @@ -951,246 +1225,387 @@ private constructor( * experiment event. Use "start" and "end" to track the time span over which the experiment * event was produced */ - @JsonDeserialize(builder = Metrics.Builder::class) @NoAutoDetect class Metrics + @JsonCreator private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonValue = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonValue = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonValue = JsonMissing.of(), + @JsonProperty("completion_tokens") + @ExcludeMissing + private val completionTokens: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing private val end: JsonField = JsonMissing.of(), + @JsonProperty("prompt_tokens") + @ExcludeMissing + private val promptTokens: JsonField = JsonMissing.of(), + @JsonProperty("start") + @ExcludeMissing + private val start: JsonField = JsonMissing.of(), + @JsonProperty("tokens") + @ExcludeMissing + private val tokens: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** This metric is deprecated */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonValue = callerFilename - private var hashCode: Int = 0 + /** This metric is deprecated */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonValue = callerFunctionname + + /** This metric is deprecated */ + @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno(): JsonValue = callerLineno /** - * A unix timestamp recording when the section of code which produced the experiment event - * started + * The number of tokens in the completion generated by the model (only set if this is an LLM + * span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) + fun completionTokens(): Optional = + Optional.ofNullable(completionTokens.getNullable("completion_tokens")) /** * A unix timestamp recording when the section of code which produced the experiment event * finished + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ fun end(): Optional = Optional.ofNullable(end.getNullable("end")) /** * The number of tokens in the prompt used to generate the experiment event (only set if * this is an LLM span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ fun promptTokens(): Optional = Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) + * A unix timestamp recording when the section of code which produced the experiment event + * started + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) + fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - /** The total number of tokens in the input and output of the experiment event. */ + /** + * The total number of tokens in the input and output of the experiment event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) /** - * A unix timestamp recording when the section of code which produced the experiment event - * started + * Returns the raw JSON value of [completionTokens]. + * + * Unlike [completionTokens], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("start") @ExcludeMissing fun _start() = start + @JsonProperty("completion_tokens") + @ExcludeMissing + fun _completionTokens(): JsonField = completionTokens /** - * A unix timestamp recording when the section of code which produced the experiment event - * finished + * Returns the raw JSON value of [end]. + * + * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("end") @ExcludeMissing fun _end() = end + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) + * Returns the raw JSON value of [promptTokens]. + * + * Unlike [promptTokens], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens + @JsonProperty("prompt_tokens") + @ExcludeMissing + fun _promptTokens(): JsonField = promptTokens /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) + * Returns the raw JSON value of [start]. + * + * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start - /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens + /** + * Returns the raw JSON value of [tokens]. + * + * Unlike [tokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tokens") @ExcludeMissing fun _tokens(): JsonField = tokens @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metrics = apply { + if (validated) { + return@apply } - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode + completionTokens() + end() + promptTokens() + start() + tokens() + validated = true } - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metrics]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metrics]. */ + class Builder internal constructor() { - private var start: JsonField = JsonMissing.of() + private var callerFilename: JsonValue = JsonMissing.of() + private var callerFunctionname: JsonValue = JsonMissing.of() + private var callerLineno: JsonValue = JsonMissing.of() + private var completionTokens: JsonField = JsonMissing.of() private var end: JsonField = JsonMissing.of() private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() + private var start: JsonField = JsonMissing.of() private var tokens: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) + callerFilename = metrics.callerFilename + callerFunctionname = metrics.callerFunctionname + callerLineno = metrics.callerLineno + completionTokens = metrics.completionTokens + end = metrics.end + promptTokens = metrics.promptTokens + start = metrics.start + tokens = metrics.tokens + additionalProperties = metrics.additionalProperties.toMutableMap() + } + + /** This metric is deprecated */ + fun callerFilename(callerFilename: JsonValue) = apply { + this.callerFilename = callerFilename + } + + /** This metric is deprecated */ + fun callerFunctionname(callerFunctionname: JsonValue) = apply { + this.callerFunctionname = callerFunctionname } + /** This metric is deprecated */ + fun callerLineno(callerLineno: JsonValue) = apply { this.callerLineno = callerLineno } + /** - * A unix timestamp recording when the section of code which produced the experiment - * event started + * The number of tokens in the completion generated by the model (only set if this is an + * LLM span) */ - fun start(start: Double) = start(JsonField.of(start)) + fun completionTokens(completionTokens: Long?) = + completionTokens(JsonField.ofNullable(completionTokens)) /** - * A unix timestamp recording when the section of code which produced the experiment - * event started + * Alias for [Builder.completionTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } + fun completionTokens(completionTokens: Long) = + completionTokens(completionTokens as Long?) /** - * A unix timestamp recording when the section of code which produced the experiment - * event finished + * Alias for calling [Builder.completionTokens] with `completionTokens.orElse(null)`. + */ + fun completionTokens(completionTokens: Optional) = + completionTokens(completionTokens.getOrNull()) + + /** + * Sets [Builder.completionTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.completionTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun end(end: Double) = end(JsonField.of(end)) + fun completionTokens(completionTokens: JsonField) = apply { + this.completionTokens = completionTokens + } /** * A unix timestamp recording when the section of code which produced the experiment * event finished */ - @JsonProperty("end") - @ExcludeMissing + fun end(end: Double?) = end(JsonField.ofNullable(end)) + + /** + * Alias for [Builder.end]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun end(end: Double) = end(end as Double?) + + /** Alias for calling [Builder.end] with `end.orElse(null)`. */ + fun end(end: Optional) = end(end.getOrNull()) + + /** + * Sets [Builder.end] to an arbitrary JSON value. + * + * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun end(end: JsonField) = apply { this.end = end } /** * The number of tokens in the prompt used to generate the experiment event (only set if * this is an LLM span) */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) + fun promptTokens(promptTokens: Long?) = promptTokens(JsonField.ofNullable(promptTokens)) /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) + * Alias for [Builder.promptTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun promptTokens(promptTokens: Long) = promptTokens(promptTokens as Long?) + + /** Alias for calling [Builder.promptTokens] with `promptTokens.orElse(null)`. */ + fun promptTokens(promptTokens: Optional) = promptTokens(promptTokens.getOrNull()) + + /** + * Sets [Builder.promptTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.promptTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("prompt_tokens") - @ExcludeMissing fun promptTokens(promptTokens: JsonField) = apply { this.promptTokens = promptTokens } /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) + * A unix timestamp recording when the section of code which produced the experiment + * event started */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) + fun start(start: Double?) = start(JsonField.ofNullable(start)) /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) + * Alias for [Builder.start]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } + fun start(start: Double) = start(start as Double?) - /** The total number of tokens in the input and output of the experiment event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) + /** Alias for calling [Builder.start] with `start.orElse(null)`. */ + fun start(start: Optional) = start(start.getOrNull()) + + /** + * Sets [Builder.start] to an arbitrary JSON value. + * + * You should usually call [Builder.start] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun start(start: JsonField) = apply { this.start = start } /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") - @ExcludeMissing + fun tokens(tokens: Long?) = tokens(JsonField.ofNullable(tokens)) + + /** + * Alias for [Builder.tokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun tokens(tokens: Long) = tokens(tokens as Long?) + + /** Alias for calling [Builder.tokens] with `tokens.orElse(null)`. */ + fun tokens(tokens: Optional) = tokens(tokens.getOrNull()) + + /** + * Sets [Builder.tokens] to an arbitrary JSON value. + * + * You should usually call [Builder.tokens] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun tokens(tokens: JsonField) = apply { this.tokens = tokens } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Metrics]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): Metrics = Metrics( - start, + callerFilename, + callerFunctionname, + callerLineno, + completionTokens, end, promptTokens, - completionTokens, + start, tokens, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metrics && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && completionTokens == other.completionTokens && end == other.end && promptTokens == other.promptTokens && start == other.start && tokens == other.tokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, completionTokens, end, promptTokens, start, tokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metrics{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, completionTokens=$completionTokens, end=$end, promptTokens=$promptTokens, start=$start, tokens=$tokens, additionalProperties=$additionalProperties}" } /** @@ -1202,279 +1617,104 @@ private constructor( * whether the summarization was covering similar concepts or not. You can use these scores to * help you sort, filter, and compare experiments */ - @JsonDeserialize(builder = Scores.Builder::class) @NoAutoDetect class Scores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Scores = apply { + if (validated) { + return@apply } - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Scores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Scores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Scores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) + additionalProperties = scores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + override fun hashCode(): Int = hashCode - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } + return /* spotless:off */ other is ExperimentEvent && id == other.id && _xactId == other._xactId && created == other.created && experimentId == other.experimentId && projectId == other.projectId && rootSpanId == other.rootSpanId && spanId == other.spanId && context == other.context && error == other.error && expected == other.expected && input == other.input && isRoot == other.isRoot && metadata == other.metadata && metrics == other.metrics && origin == other.origin && output == other.output && scores == other.scores && spanAttributes == other.spanAttributes && spanParents == other.spanParents && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, created, experimentId, projectId, rootSpanId, spanId, context, error, expected, input, isRoot, metadata, metrics, origin, output, scores, spanAttributes, spanParents, tags, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "ExperimentEvent{id=$id, _xactId=$_xactId, created=$created, experimentId=$experimentId, projectId=$projectId, rootSpanId=$rootSpanId, spanId=$spanId, context=$context, error=$error, expected=$expected, input=$input, isRoot=$isRoot, metadata=$metadata, metrics=$metrics, origin=$origin, output=$output, scores=$scores, spanAttributes=$spanAttributes, spanParents=$spanParents, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParams.kt index 02de4d52..2558dfff 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParams.kt @@ -3,37 +3,62 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects +/** Log feedback for a set of experiment events */ class ExperimentFeedbackParams -constructor( +private constructor( private val experimentId: String, - private val feedback: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId - fun feedback(): List = feedback + /** + * A list of experiment feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = body.feedback() - @JvmSynthetic - internal fun getBody(): ExperimentFeedbackBody { - return ExperimentFeedbackBody(feedback, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _feedback(): JsonField> = body._feedback() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -42,221 +67,364 @@ constructor( } } - @JsonDeserialize(builder = ExperimentFeedbackBody.Builder::class) @NoAutoDetect - class ExperimentFeedbackBody - internal constructor( - private val feedback: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("feedback") + @ExcludeMissing + private val feedback: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of experiment feedback items */ - @JsonProperty("feedback") fun feedback(): List? = feedback + /** + * A list of experiment feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = feedback.getRequired("feedback") + + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feedback") + @ExcludeMissing + fun _feedback(): JsonField> = feedback @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ExperimentFeedbackBody && - this.feedback == other.feedback && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(feedback, additionalProperties) - } - return hashCode + feedback().forEach { it.validate() } + validated = true } - override fun toString() = - "ExperimentFeedbackBody{feedback=$feedback, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var feedback: List? = null + private var feedback: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(experimentFeedbackBody: ExperimentFeedbackBody) = apply { - this.feedback = experimentFeedbackBody.feedback - additionalProperties(experimentFeedbackBody.additionalProperties) + internal fun from(body: Body) = apply { + feedback = body.feedback.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of experiment feedback items */ - @JsonProperty("feedback") - fun feedback(feedback: List) = apply { - this.feedback = feedback + fun feedback(feedback: List) = feedback(JsonField.of(feedback)) + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + this.feedback = feedback.map { it.toMutableList() } + } + + /** + * Adds a single [FeedbackExperimentItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackExperimentItem) = apply { + this.feedback = + (this.feedback ?: JsonField.of(mutableListOf())).also { + checkKnown("feedback", it).add(feedback) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ExperimentFeedbackBody = - ExperimentFeedbackBody( - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("feedback", feedback).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && feedback == other.feedback && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ExperimentFeedbackParams && - this.experimentId == other.experimentId && - this.feedback == other.feedback && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(feedback, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - experimentId, - feedback, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ExperimentFeedbackParams{experimentId=$experimentId, feedback=$feedback, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{feedback=$feedback, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentFeedbackParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentFeedbackParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var feedback: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(experimentFeedbackParams: ExperimentFeedbackParams) = apply { - this.experimentId = experimentFeedbackParams.experimentId - this.feedback(experimentFeedbackParams.feedback) - additionalQueryParams(experimentFeedbackParams.additionalQueryParams) - additionalHeaders(experimentFeedbackParams.additionalHeaders) - additionalBodyProperties(experimentFeedbackParams.additionalBodyProperties) + experimentId = experimentFeedbackParams.experimentId + body = experimentFeedbackParams.body.toBuilder() + additionalHeaders = experimentFeedbackParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentFeedbackParams.additionalQueryParams.toBuilder() } /** Experiment id */ fun experimentId(experimentId: String) = apply { this.experimentId = experimentId } /** A list of experiment feedback items */ - fun feedback(feedback: List) = apply { - this.feedback.clear() - this.feedback.addAll(feedback) + fun feedback(feedback: List) = apply { body.feedback(feedback) } + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + body.feedback(feedback) } - /** A list of experiment feedback items */ - fun addFeedback(feedback: FeedbackExperimentItem) = apply { this.feedback.add(feedback) } + /** + * Adds a single [FeedbackExperimentItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackExperimentItem) = apply { body.addFeedback(feedback) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ExperimentFeedbackParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentFeedbackParams = ExperimentFeedbackParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("experimentId", experimentId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentFeedbackParams && experimentId == other.experimentId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentFeedbackParams{experimentId=$experimentId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchParams.kt index 9f90dc28..93faaa22 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchParams.kt @@ -3,44 +3,101 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in an experiment. Equivalent to the POST form of the same path, but with the + * parameters in the URL query rather than in the request body. For more complex queries, use the + * `POST /btql` endpoint. + */ class ExperimentFetchParams -constructor( +private constructor( private val experimentId: String, private val limit: Long?, private val maxRootSpanId: String?, private val maxXactId: String?, private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + */ fun limit(): Optional = Optional.ofNullable(limit) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxXactId(): Optional = Optional.ofNullable(maxXactId) + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + */ fun version(): Optional = Optional.ofNullable(version) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.maxRootSpanId?.let { params.put("max_root_span_id", listOf(it.toString())) } - this.maxXactId?.let { params.put("max_xact_id", listOf(it.toString())) } - this.version?.let { params.put("version", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + limit?.let { put("limit", it.toString()) } + maxRootSpanId?.let { put("max_root_span_id", it) } + maxXactId?.let { put("max_xact_id", it) } + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -49,67 +106,42 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExperimentFetchParams && - this.experimentId == other.experimentId && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - experimentId, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ExperimentFetchParams{experimentId=$experimentId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentFetchParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentFetchParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null private var limit: Long? = null private var maxRootSpanId: String? = null private var maxXactId: String? = null private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(experimentFetchParams: ExperimentFetchParams) = apply { - this.experimentId = experimentFetchParams.experimentId - this.limit = experimentFetchParams.limit - this.maxRootSpanId = experimentFetchParams.maxRootSpanId - this.maxXactId = experimentFetchParams.maxXactId - this.version = experimentFetchParams.version - additionalQueryParams(experimentFetchParams.additionalQueryParams) - additionalHeaders(experimentFetchParams.additionalHeaders) + experimentId = experimentFetchParams.experimentId + limit = experimentFetchParams.limit + maxRootSpanId = experimentFetchParams.maxRootSpanId + maxXactId = experimentFetchParams.maxXactId + version = experimentFetchParams.version + additionalHeaders = experimentFetchParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentFetchParams.additionalQueryParams.toBuilder() } /** Experiment id */ @@ -130,7 +162,17 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -144,7 +186,11 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { this.maxRootSpanId = maxRootSpanId } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -158,7 +204,10 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { this.maxXactId = maxXactId } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) /** * Retrieve a snapshot of events from a past time @@ -166,57 +215,143 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { this.version = version } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ExperimentFetchParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentFetchParams = ExperimentFetchParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, + checkRequired("experimentId", experimentId), limit, maxRootSpanId, maxXactId, version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentFetchParams && experimentId == other.experimentId && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, limit, maxRootSpanId, maxXactId, version, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentFetchParams{experimentId=$experimentId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParams.kt index b208f3c8..180f8e6a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParams.kt @@ -3,61 +3,162 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in an experiment. Equivalent to the GET form of the same path, but with the + * parameters in the request body rather than in the URL query. For more complex queries, use the + * `POST /btql` endpoint. + */ class ExperimentFetchPostParams -constructor( +private constructor( private val experimentId: String, - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId - fun cursor(): Optional = Optional.ofNullable(cursor) - - fun filters(): Optional> = Optional.ofNullable(filters) - - fun limit(): Optional = Optional.ofNullable(limit) - - fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) - - fun maxXactId(): Optional = Optional.ofNullable(maxXactId) - - fun version(): Optional = Optional.ofNullable(version) - - @JvmSynthetic - internal fun getBody(): ExperimentFetchPostBody { - return ExperimentFetchPostBody( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * An opaque string to be used as a cursor for the next page of results, in order from latest to + * earliest. + * + * The string can be obtained directly from the `cursor` property of the previous fetch query + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun cursor(): Optional = body.cursor() + + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = body.limit() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxRootSpanId(): Optional = body.maxRootSpanId() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxXactId(): Optional = body.maxXactId() + + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = body.version() + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _cursor(): JsonField = body._cursor() + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _limit(): JsonField = body._limit() + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxRootSpanId(): JsonField = body._maxRootSpanId() + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxXactId(): JsonField = body._maxXactId() + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _version(): JsonField = body._version() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -66,39 +167,40 @@ constructor( } } - @JsonDeserialize(builder = ExperimentFetchPostBody.Builder::class) @NoAutoDetect - class ExperimentFetchPostBody - internal constructor( - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonProperty("limit") + @ExcludeMissing + private val limit: JsonField = JsonMissing.of(), + @JsonProperty("max_root_span_id") + @ExcludeMissing + private val maxRootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("max_xact_id") + @ExcludeMissing + private val maxXactId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * An opaque string to be used as a cursor for the next page of results, in order from * latest to earliest. * * The string can be obtained directly from the `cursor` property of the previous fetch * query - */ - @JsonProperty("cursor") fun cursor(): String? = cursor - - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("filters") fun filters(): List? = filters + fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) /** * limit the number of traces fetched @@ -114,8 +216,11 @@ constructor( * The `limit` parameter controls the number of full traces to return. So you may end up * with more individual rows than the specified limit if you are fetching events containing * traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("limit") fun limit(): Long? = limit + fun limit(): Optional = Optional.ofNullable(limit.getNullable("limit")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -128,8 +233,12 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_root_span_id") fun maxRootSpanId(): String? = maxRootSpanId + fun maxRootSpanId(): Optional = + Optional.ofNullable(maxRootSpanId.getNullable("max_root_span_id")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -142,81 +251,107 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_xact_id") fun maxXactId(): String? = maxXactId + fun maxXactId(): Optional = + Optional.ofNullable(maxXactId.getNullable("max_xact_id")) /** * Retrieve a snapshot of events from a past time * * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_root_span_id") + @ExcludeMissing + fun _maxRootSpanId(): JsonField = maxRootSpanId + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("max_xact_id") @ExcludeMissing fun _maxXactId(): JsonField = maxXactId + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("version") fun version(): String? = version + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ExperimentFetchPostBody && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalProperties, - ) - } - return hashCode + cursor() + limit() + maxRootSpanId() + maxXactId() + version() + validated = true } - override fun toString() = - "ExperimentFetchPostBody{cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var cursor: String? = null - private var filters: List? = null - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null + private var cursor: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var maxRootSpanId: JsonField = JsonMissing.of() + private var maxXactId: JsonField = JsonMissing.of() + private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(experimentFetchPostBody: ExperimentFetchPostBody) = apply { - this.cursor = experimentFetchPostBody.cursor - this.filters = experimentFetchPostBody.filters - this.limit = experimentFetchPostBody.limit - this.maxRootSpanId = experimentFetchPostBody.maxRootSpanId - this.maxXactId = experimentFetchPostBody.maxXactId - this.version = experimentFetchPostBody.version - additionalProperties(experimentFetchPostBody.additionalProperties) + internal fun from(body: Body) = apply { + cursor = body.cursor + limit = body.limit + maxRootSpanId = body.maxRootSpanId + maxXactId = body.maxXactId + version = body.version + additionalProperties = body.additionalProperties.toMutableMap() } /** @@ -226,18 +361,19 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - @JsonProperty("cursor") fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters - * are supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("filters") - fun filters(filters: List) = apply { this.filters = filters } + fun cursor(cursor: JsonField) = apply { this.cursor = cursor } /** * limit the number of traces fetched @@ -254,7 +390,26 @@ constructor( * with more individual rows than the specified limit if you are fetching events * containing traces. */ - @JsonProperty("limit") fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = limit(JsonField.ofNullable(limit)) + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -268,8 +423,23 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_root_span_id") - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = + maxRootSpanId(JsonField.ofNullable(maxRootSpanId)) + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + this.maxRootSpanId = maxRootSpanId + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -283,8 +453,19 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_xact_id") - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = maxXactId(JsonField.ofNullable(maxXactId)) + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxXactId(maxXactId: JsonField) = apply { this.maxXactId = maxXactId } /** * Retrieve a snapshot of events from a past time @@ -293,110 +474,103 @@ constructor( * use the `max_xact_id` returned by a past fetch as the version to reproduce that exact * fetch. */ - @JsonProperty("version") fun version(version: String) = apply { this.version = version } + fun version(version: String?) = version(JsonField.ofNullable(version)) + + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ExperimentFetchPostBody = - ExperimentFetchPostBody( + 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. + */ + fun build(): Body = + Body( cursor, - filters?.toUnmodifiable(), limit, maxRootSpanId, maxXactId, version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && cursor == other.cursor && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ExperimentFetchPostParams && - this.experimentId == other.experimentId && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(cursor, limit, maxRootSpanId, maxXactId, version, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - experimentId, - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ExperimentFetchPostParams{experimentId=$experimentId, cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{cursor=$cursor, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentFetchPostParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentFetchPostParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var cursor: String? = null - private var filters: MutableList = mutableListOf() - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(experimentFetchPostParams: ExperimentFetchPostParams) = apply { - this.experimentId = experimentFetchPostParams.experimentId - this.cursor = experimentFetchPostParams.cursor - this.filters(experimentFetchPostParams.filters ?: listOf()) - this.limit = experimentFetchPostParams.limit - this.maxRootSpanId = experimentFetchPostParams.maxRootSpanId - this.maxXactId = experimentFetchPostParams.maxXactId - this.version = experimentFetchPostParams.version - additionalQueryParams(experimentFetchPostParams.additionalQueryParams) - additionalHeaders(experimentFetchPostParams.additionalHeaders) - additionalBodyProperties(experimentFetchPostParams.additionalBodyProperties) + experimentId = experimentFetchPostParams.experimentId + body = experimentFetchPostParams.body.toBuilder() + additionalHeaders = experimentFetchPostParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentFetchPostParams.additionalQueryParams.toBuilder() } /** Experiment id */ @@ -409,30 +583,18 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = apply { body.cursor(cursor) } - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. - * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. - */ - fun filters(filters: List) = apply { - this.filters.clear() - this.filters.addAll(filters) - } + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun addFilter(filter: PathLookupFilter) = apply { this.filters.add(filter) } + fun cursor(cursor: JsonField) = apply { body.cursor(cursor) } /** * limit the number of traces fetched @@ -449,7 +611,25 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { body.limit(limit) } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { body.limit(limit) } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -463,7 +643,22 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { body.maxRootSpanId(maxRootSpanId) } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + body.maxRootSpanId(maxRootSpanId) + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -477,7 +672,19 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { body.maxXactId(maxXactId) } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxXactId(maxXactId: JsonField) = apply { body.maxXactId(maxXactId) } /** * Retrieve a snapshot of events from a past time @@ -485,74 +692,167 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { body.version(version) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { body.version(version) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ExperimentFetchPostParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentFetchPostParams = ExperimentFetchPostParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - cursor, - if (filters.size == 0) null else filters.toUnmodifiable(), - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("experimentId", experimentId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentFetchPostParams && experimentId == other.experimentId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentFetchPostParams{experimentId=$experimentId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentInsertParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentInsertParams.kt index b03547c6..16a00bbe 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentInsertParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentInsertParams.kt @@ -2,49 +2,63 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.BaseDeserializer -import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects -import java.util.Optional +/** Insert a set of events into the experiment */ class ExperimentInsertParams -constructor( +private constructor( private val experimentId: String, - private val events: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId - fun events(): List = events + /** + * A list of experiment events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = body.events() - @JvmSynthetic - internal fun getBody(): ExperimentInsertBody { - return ExperimentInsertBody(events, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _events(): JsonField> = body._events() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + @JvmSynthetic internal fun _body(): Body = body - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -53,358 +67,361 @@ constructor( } } - @JsonDeserialize(builder = ExperimentInsertBody.Builder::class) @NoAutoDetect - class ExperimentInsertBody - internal constructor( - private val events: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of experiment events to insert */ - @JsonProperty("events") fun events(): List? = events + /** + * A list of experiment events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") + + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") + @ExcludeMissing + fun _events(): JsonField> = events @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ExperimentInsertBody && - this.events == other.events && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(events, additionalProperties) - } - return hashCode + events().forEach { it.validate() } + validated = true } - override fun toString() = - "ExperimentInsertBody{events=$events, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var events: List? = null + private var events: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(experimentInsertBody: ExperimentInsertBody) = apply { - this.events = experimentInsertBody.events - additionalProperties(experimentInsertBody.additionalProperties) + internal fun from(body: Body) = apply { + events = body.events.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of experiment events to insert */ - @JsonProperty("events") fun events(events: List) = apply { this.events = events } + fun events(events: List) = events(JsonField.of(events)) + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } + + /** + * Adds a single [InsertExperimentEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertExperimentEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ExperimentInsertBody = - ExperimentInsertBody( - checkNotNull(events) { "`events` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("events", events).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && events == other.events && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ExperimentInsertParams && - this.experimentId == other.experimentId && - this.events == other.events && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - experimentId, - events, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ExperimentInsertParams{experimentId=$experimentId, events=$events, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = "Body{events=$events, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentInsertParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentInsertParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var events: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(experimentInsertParams: ExperimentInsertParams) = apply { - this.experimentId = experimentInsertParams.experimentId - this.events(experimentInsertParams.events) - additionalQueryParams(experimentInsertParams.additionalQueryParams) - additionalHeaders(experimentInsertParams.additionalHeaders) - additionalBodyProperties(experimentInsertParams.additionalBodyProperties) + experimentId = experimentInsertParams.experimentId + body = experimentInsertParams.body.toBuilder() + additionalHeaders = experimentInsertParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentInsertParams.additionalQueryParams.toBuilder() } /** Experiment id */ fun experimentId(experimentId: String) = apply { this.experimentId = experimentId } /** A list of experiment events to insert */ - fun events(events: List) = apply { - this.events.clear() - this.events.addAll(events) - } + fun events(events: List) = apply { body.events(events) } + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun events(events: JsonField>) = apply { body.events(events) } + + /** + * Adds a single [InsertExperimentEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertExperimentEvent) = apply { body.addEvent(event) } - /** A list of experiment events to insert */ - fun addEvent(event: Event) = apply { this.events.add(event) } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): ExperimentInsertParams = - ExperimentInsertParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - checkNotNull(events) { "`events` is required but was not set" }.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(using = Event.Deserializer::class) - @JsonSerialize(using = Event.Serializer::class) - class Event - private constructor( - private val insertExperimentEventReplace: InsertExperimentEventReplace? = null, - private val insertExperimentEventMerge: InsertExperimentEventMerge? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - fun insertExperimentEventReplace(): Optional = - Optional.ofNullable(insertExperimentEventReplace) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun insertExperimentEventMerge(): Optional = - Optional.ofNullable(insertExperimentEventMerge) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun isInsertExperimentEventReplace(): Boolean = insertExperimentEventReplace != null + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - fun isInsertExperimentEventMerge(): Boolean = insertExperimentEventMerge != null + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - fun asInsertExperimentEventReplace(): InsertExperimentEventReplace = - insertExperimentEventReplace.getOrThrow("insertExperimentEventReplace") + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun asInsertExperimentEventMerge(): InsertExperimentEventMerge = - insertExperimentEventMerge.getOrThrow("insertExperimentEventMerge") + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun _json(): Optional = Optional.ofNullable(_json) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - fun accept(visitor: Visitor): T { - return when { - insertExperimentEventReplace != null -> - visitor.visitInsertExperimentEventReplace(insertExperimentEventReplace) - insertExperimentEventMerge != null -> - visitor.visitInsertExperimentEventMerge(insertExperimentEventMerge) - else -> visitor.unknown(_json) - } + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun validate(): Event = apply { - if (!validated) { - if (insertExperimentEventReplace == null && insertExperimentEventMerge == null) { - throw BraintrustInvalidDataException("Unknown Event: $_json") - } - insertExperimentEventReplace?.validate() - insertExperimentEventMerge?.validate() - validated = true - } + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - return other is Event && - this.insertExperimentEventReplace == other.insertExperimentEventReplace && - this.insertExperimentEventMerge == other.insertExperimentEventMerge + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - override fun hashCode(): Int { - return Objects.hash(insertExperimentEventReplace, insertExperimentEventMerge) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - override fun toString(): String { - return when { - insertExperimentEventReplace != null -> - "Event{insertExperimentEventReplace=$insertExperimentEventReplace}" - insertExperimentEventMerge != null -> - "Event{insertExperimentEventMerge=$insertExperimentEventMerge}" - _json != null -> "Event{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Event") - } + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - companion object { + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmStatic - fun ofInsertExperimentEventReplace( - insertExperimentEventReplace: InsertExperimentEventReplace - ) = Event(insertExperimentEventReplace = insertExperimentEventReplace) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic - fun ofInsertExperimentEventMerge( - insertExperimentEventMerge: InsertExperimentEventMerge - ) = Event(insertExperimentEventMerge = insertExperimentEventMerge) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - interface Visitor { - - fun visitInsertExperimentEventReplace( - insertExperimentEventReplace: InsertExperimentEventReplace - ): T - - fun visitInsertExperimentEventMerge( - insertExperimentEventMerge: InsertExperimentEventMerge - ): T + /** + * Returns an immutable instance of [ExperimentInsertParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ExperimentInsertParams = + ExperimentInsertParams( + checkRequired("experimentId", experimentId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Event: $json") - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class Deserializer : BaseDeserializer(Event::class) { + return /* spotless:off */ other is ExperimentInsertParams && experimentId == other.experimentId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - override fun ObjectCodec.deserialize(node: JsonNode): Event { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { - it.validate() - } - ?.let { - return Event(insertExperimentEventReplace = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Event(insertExperimentEventMerge = it, _json = json) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - return Event(_json = json) - } - } - - class Serializer : BaseSerializer(Event::class) { - - override fun serialize( - value: Event, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.insertExperimentEventReplace != null -> - generator.writeObject(value.insertExperimentEventReplace) - value.insertExperimentEventMerge != null -> - generator.writeObject(value.insertExperimentEventMerge) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Event") - } - } - } - } + override fun toString() = + "ExperimentInsertParams{experimentId=$experimentId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPage.kt index 18eb99a7..3c803f0b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ExperimentService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all experiments. The experiments are sorted by creation date, with the most + * recently-created experiments coming first + */ class ExperimentListPage private constructor( private val experimentsService: ExperimentService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ExperimentListPage && - this.experimentsService == other.experimentsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ExperimentListPage && experimentsService == other.experimentsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - experimentsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentsService, params, response) /* spotless:on */ override fun toString() = "ExperimentListPage{experimentsService=$experimentsService, params=$params, response=$response}" @@ -89,25 +86,20 @@ private constructor( fun of( experimentsService: ExperimentService, params: ExperimentListParams, - response: Response - ) = - ExperimentListPage( - experimentsService, - params, - response, - ) + response: Response, + ) = ExperimentListPage(experimentsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -117,11 +109,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -131,20 +127,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ExperimentListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ExperimentListPage]. */ @JvmStatic fun builder() = Builder() } @@ -161,22 +154,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ExperimentListPage, - ) : Iterable { + class AutoPager(private val firstPage: ExperimentListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -185,7 +178,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPageAsync.kt index 2b5d3b79..cfdcebc5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ExperimentServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all experiments. The experiments are sorted by creation date, with the most + * recently-created experiments coming first + */ class ExperimentListPageAsync private constructor( private val experimentsService: ExperimentServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ExperimentListPageAsync && - this.experimentsService == other.experimentsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ExperimentListPageAsync && experimentsService == other.experimentsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - experimentsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentsService, params, response) /* spotless:on */ override fun toString() = "ExperimentListPageAsync{experimentsService=$experimentsService, params=$params, response=$response}" @@ -92,25 +88,20 @@ private constructor( fun of( experimentsService: ExperimentServiceAsync, params: ExperimentListParams, - response: Response - ) = - ExperimentListPageAsync( - experimentsService, - params, - response, - ) + response: Response, + ) = ExperimentListPageAsync(experimentsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +111,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +129,19 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ExperimentListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +158,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ExperimentListPageAsync, - ) { + class AutoPager(private val firstPage: ExperimentListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Experiment) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +187,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListParams.kt index 6c36c064..6e2f5bef 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all experiments. The experiments are sorted by creation date, with the most + * recently-created experiments coming first + */ class ExperimentListParams -constructor( +private constructor( private val endingBefore: String?, private val experimentName: String?, private val ids: Ids?, @@ -30,92 +36,93 @@ constructor( private val projectId: String?, private val projectName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** Name of the experiment to search for */ fun experimentName(): Optional = Optional.ofNullable(experimentName) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.experimentName?.let { params.put("experiment_name", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExperimentListParams && - this.endingBefore == other.endingBefore && - this.experimentName == other.experimentName && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - experimentName, - ids, - limit, - orgName, - projectId, - projectName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ExperimentListParams{endingBefore=$endingBefore, experimentName=$experimentName, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + experimentName?.let { put("experiment_name", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): ExperimentListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ExperimentListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var experimentName: String? = null @@ -125,21 +132,21 @@ constructor( private var projectId: String? = null private var projectName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(experimentListParams: ExperimentListParams) = apply { - this.endingBefore = experimentListParams.endingBefore - this.experimentName = experimentListParams.experimentName - this.ids = experimentListParams.ids - this.limit = experimentListParams.limit - this.orgName = experimentListParams.orgName - this.projectId = experimentListParams.projectId - this.projectName = experimentListParams.projectName - this.startingAfter = experimentListParams.startingAfter - additionalQueryParams(experimentListParams.additionalQueryParams) - additionalHeaders(experimentListParams.additionalHeaders) + endingBefore = experimentListParams.endingBefore + experimentName = experimentListParams.experimentName + ids = experimentListParams.ids + limit = experimentListParams.limit + orgName = experimentListParams.orgName + projectId = experimentListParams.projectId + projectName = experimentListParams.projectName + startingAfter = experimentListParams.startingAfter + additionalHeaders = experimentListParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentListParams.additionalQueryParams.toBuilder() } /** @@ -149,40 +156,63 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } + + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** Name of the experiment to search for */ - fun experimentName(experimentName: String) = apply { this.experimentName = experimentName } + fun experimentName(experimentName: String?) = apply { this.experimentName = experimentName } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.experimentName] with `experimentName.orElse(null)`. */ + fun experimentName(experimentName: Optional) = + experimentName(experimentName.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** * Pagination cursor id. @@ -191,48 +221,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ExperimentListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ExperimentListParams = ExperimentListParams( endingBefore, @@ -243,11 +340,15 @@ constructor( projectId, projectName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -257,8 +358,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -281,35 +380,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -318,21 +405,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -344,12 +442,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -360,4 +458,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentListParams && endingBefore == other.endingBefore && experimentName == other.experimentName && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, experimentName, ids, limit, orgName, projectId, projectName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentListParams{endingBefore=$endingBefore, experimentName=$experimentName, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParams.kt index 3062382b..54ba50ec 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an experiment object by its id */ class ExperimentRetrieveParams -constructor( +private constructor( private val experimentId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExperimentRetrieveParams && - this.experimentId == other.experimentId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - experimentId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ExperimentRetrieveParams{experimentId=$experimentId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentRetrieveParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(experimentRetrieveParams: ExperimentRetrieveParams) = apply { - this.experimentId = experimentRetrieveParams.experimentId - additionalQueryParams(experimentRetrieveParams.additionalQueryParams) - additionalHeaders(experimentRetrieveParams.additionalHeaders) + experimentId = experimentRetrieveParams.experimentId + additionalHeaders = experimentRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentRetrieveParams.additionalQueryParams.toBuilder() } /** Experiment id */ fun experimentId(experimentId: String) = apply { this.experimentId = experimentId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ExperimentRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentRetrieveParams = ExperimentRetrieveParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("experimentId", experimentId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentRetrieveParams && experimentId == other.experimentId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentRetrieveParams{experimentId=$experimentId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParams.kt index c72fa655..10cf6fc7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParams.kt @@ -3,38 +3,54 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Summarize experiment */ class ExperimentSummarizeParams -constructor( +private constructor( private val experimentId: String, private val comparisonExperimentId: String?, private val summarizeScores: Boolean?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId + /** + * The experiment to compare against, if summarizing scores and metrics. If omitted, will fall + * back to the `base_exp_id` stored in the experiment metadata, and then to the most recent + * experiment run in the same project. Must pass `summarize_scores=true` for this id to be used + */ fun comparisonExperimentId(): Optional = Optional.ofNullable(comparisonExperimentId) + /** + * Whether to summarize the scores and metrics. If false (or omitted), only the metadata will be + * returned. + */ fun summarizeScores(): Optional = Optional.ofNullable(summarizeScores) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.comparisonExperimentId?.let { - params.put("comparison_experiment_id", listOf(it.toString())) - } - this.summarizeScores?.let { params.put("summarize_scores", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + comparisonExperimentId?.let { put("comparison_experiment_id", it) } + summarizeScores?.let { put("summarize_scores", it.toString()) } + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -43,59 +59,38 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ExperimentSummarizeParams && - this.experimentId == other.experimentId && - this.comparisonExperimentId == other.comparisonExperimentId && - this.summarizeScores == other.summarizeScores && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - experimentId, - comparisonExperimentId, - summarizeScores, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ExperimentSummarizeParams{experimentId=$experimentId, comparisonExperimentId=$comparisonExperimentId, summarizeScores=$summarizeScores, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentSummarizeParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentSummarizeParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null private var comparisonExperimentId: String? = null private var summarizeScores: Boolean? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(experimentSummarizeParams: ExperimentSummarizeParams) = apply { - this.experimentId = experimentSummarizeParams.experimentId - this.comparisonExperimentId = experimentSummarizeParams.comparisonExperimentId - this.summarizeScores = experimentSummarizeParams.summarizeScores - additionalQueryParams(experimentSummarizeParams.additionalQueryParams) - additionalHeaders(experimentSummarizeParams.additionalHeaders) + experimentId = experimentSummarizeParams.experimentId + comparisonExperimentId = experimentSummarizeParams.comparisonExperimentId + summarizeScores = experimentSummarizeParams.summarizeScores + additionalHeaders = experimentSummarizeParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentSummarizeParams.additionalQueryParams.toBuilder() } /** Experiment id */ @@ -107,65 +102,166 @@ constructor( * recent experiment run in the same project. Must pass `summarize_scores=true` for this id * to be used */ - fun comparisonExperimentId(comparisonExperimentId: String) = apply { + fun comparisonExperimentId(comparisonExperimentId: String?) = apply { this.comparisonExperimentId = comparisonExperimentId } + /** + * Alias for calling [Builder.comparisonExperimentId] with + * `comparisonExperimentId.orElse(null)`. + */ + fun comparisonExperimentId(comparisonExperimentId: Optional) = + comparisonExperimentId(comparisonExperimentId.getOrNull()) + /** * Whether to summarize the scores and metrics. If false (or omitted), only the metadata * will be returned. */ - fun summarizeScores(summarizeScores: Boolean) = apply { + fun summarizeScores(summarizeScores: Boolean?) = apply { this.summarizeScores = summarizeScores } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** + * Alias for [Builder.summarizeScores]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun summarizeScores(summarizeScores: Boolean) = summarizeScores(summarizeScores as Boolean?) + + /** Alias for calling [Builder.summarizeScores] with `summarizeScores.orElse(null)`. */ + fun summarizeScores(summarizeScores: Optional) = + summarizeScores(summarizeScores.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ExperimentSummarizeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentSummarizeParams = ExperimentSummarizeParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, + checkRequired("experimentId", experimentId), comparisonExperimentId, summarizeScores, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentSummarizeParams && experimentId == other.experimentId && comparisonExperimentId == other.comparisonExperimentId && summarizeScores == other.summarizeScores && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, comparisonExperimentId, summarizeScores, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentSummarizeParams{experimentId=$experimentId, comparisonExperimentId=$comparisonExperimentId, summarizeScores=$summarizeScores, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentUpdateParams.kt index bac822b2..74a29345 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ExperimentUpdateParams.kt @@ -3,69 +3,174 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update an experiment object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ class ExperimentUpdateParams -constructor( +private constructor( private val experimentId: String, - private val baseExpId: String?, - private val datasetId: String?, - private val datasetVersion: String?, - private val description: String?, - private val metadata: Metadata?, - private val name: String?, - private val public_: Boolean?, - private val repoInfo: RepoInfo?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Experiment id */ fun experimentId(): String = experimentId - fun baseExpId(): Optional = Optional.ofNullable(baseExpId) - - fun datasetId(): Optional = Optional.ofNullable(datasetId) - - fun datasetVersion(): Optional = Optional.ofNullable(datasetVersion) - - fun description(): Optional = Optional.ofNullable(description) - - fun metadata(): Optional = Optional.ofNullable(metadata) - - fun name(): Optional = Optional.ofNullable(name) - - fun public_(): Optional = Optional.ofNullable(public_) - - fun repoInfo(): Optional = Optional.ofNullable(repoInfo) - - @JvmSynthetic - internal fun getBody(): ExperimentUpdateBody { - return ExperimentUpdateBody( - baseExpId, - datasetId, - datasetVersion, - description, - metadata, - name, - public_, - repoInfo, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Id of default base experiment to compare against when viewing this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baseExpId(): Optional = body.baseExpId() + + /** + * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun datasetId(): Optional = body.datasetId() + + /** + * Version number of the linked dataset the experiment was run against. This can be used to + * reproduce the experiment after the dataset has been modified. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun datasetVersion(): Optional = body.datasetVersion() + + /** + * Textual description of the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * User-controlled metadata about the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * Name of the experiment. Within a project, experiment names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Whether or not the experiment is public. Public experiments can be viewed by anybody inside + * or outside the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun public_(): Optional = body.public_() + + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun repoInfo(): Optional = body.repoInfo() + + /** + * Returns the raw JSON value of [baseExpId]. + * + * Unlike [baseExpId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _baseExpId(): JsonField = body._baseExpId() + + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _datasetId(): JsonField = body._datasetId() + + /** + * Returns the raw JSON value of [datasetVersion]. + * + * Unlike [datasetVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _datasetVersion(): JsonField = body._datasetVersion() + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * 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 [public_]. + * + * Unlike [public_], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _public_(): JsonField = body._public_() + + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _repoInfo(): JsonField = body._repoInfo() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -74,186 +179,392 @@ constructor( } } - @JsonDeserialize(builder = ExperimentUpdateBody.Builder::class) @NoAutoDetect - class ExperimentUpdateBody - internal constructor( - private val baseExpId: String?, - private val datasetId: String?, - private val datasetVersion: String?, - private val description: String?, - private val metadata: Metadata?, - private val name: String?, - private val public_: Boolean?, - private val repoInfo: RepoInfo?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("base_exp_id") + @ExcludeMissing + private val baseExpId: JsonField = JsonMissing.of(), + @JsonProperty("dataset_id") + @ExcludeMissing + private val datasetId: JsonField = JsonMissing.of(), + @JsonProperty("dataset_version") + @ExcludeMissing + private val datasetVersion: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("public") + @ExcludeMissing + private val public_: JsonField = JsonMissing.of(), + @JsonProperty("repo_info") + @ExcludeMissing + private val repoInfo: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") fun baseExpId(): String? = baseExpId + /** + * Id of default base experiment to compare against when viewing this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun baseExpId(): Optional = + Optional.ofNullable(baseExpId.getNullable("base_exp_id")) /** * Identifier of the linked dataset, or null if the experiment is not linked to a dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("dataset_id") fun datasetId(): String? = datasetId + fun datasetId(): Optional = Optional.ofNullable(datasetId.getNullable("dataset_id")) /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("dataset_version") fun datasetVersion(): String? = datasetVersion + fun datasetVersion(): Optional = + Optional.ofNullable(datasetVersion.getNullable("dataset_version")) - /** Textual description of the experiment */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") fun metadata(): Metadata? = metadata + /** + * User-controlled metadata about the experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the experiment. Within a project, experiment names are unique + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("public") fun public_(): Boolean? = public_ + fun public_(): Optional = Optional.ofNullable(public_.getNullable("public")) - /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") fun repoInfo(): RepoInfo? = repoInfo + /** + * Metadata about the state of the repo when the experiment was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun repoInfo(): Optional = Optional.ofNullable(repoInfo.getNullable("repo_info")) + + /** + * Returns the raw JSON value of [baseExpId]. + * + * Unlike [baseExpId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("base_exp_id") @ExcludeMissing fun _baseExpId(): JsonField = baseExpId + + /** + * Returns the raw JSON value of [datasetId]. + * + * Unlike [datasetId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_id") @ExcludeMissing fun _datasetId(): JsonField = datasetId + + /** + * Returns the raw JSON value of [datasetVersion]. + * + * Unlike [datasetVersion], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("dataset_version") + @ExcludeMissing + fun _datasetVersion(): JsonField = datasetVersion + + /** + * 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 [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * 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 [public_]. + * + * Unlike [public_], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("public") @ExcludeMissing fun _public_(): JsonField = public_ + + /** + * Returns the raw JSON value of [repoInfo]. + * + * Unlike [repoInfo], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("repo_info") @ExcludeMissing fun _repoInfo(): JsonField = repoInfo @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ExperimentUpdateBody && - this.baseExpId == other.baseExpId && - this.datasetId == other.datasetId && - this.datasetVersion == other.datasetVersion && - this.description == other.description && - this.metadata == other.metadata && - this.name == other.name && - this.public_ == other.public_ && - this.repoInfo == other.repoInfo && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - baseExpId, - datasetId, - datasetVersion, - description, - metadata, - name, - public_, - repoInfo, - additionalProperties, - ) - } - return hashCode + baseExpId() + datasetId() + datasetVersion() + description() + metadata().ifPresent { it.validate() } + name() + public_() + repoInfo().ifPresent { it.validate() } + validated = true } - override fun toString() = - "ExperimentUpdateBody{baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var baseExpId: String? = null - private var datasetId: String? = null - private var datasetVersion: String? = null - private var description: String? = null - private var metadata: Metadata? = null - private var name: String? = null - private var public_: Boolean? = null - private var repoInfo: RepoInfo? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var baseExpId: JsonField = JsonMissing.of() + private var datasetId: JsonField = JsonMissing.of() + private var datasetVersion: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var public_: JsonField = JsonMissing.of() + private var repoInfo: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(experimentUpdateBody: ExperimentUpdateBody) = apply { - this.baseExpId = experimentUpdateBody.baseExpId - this.datasetId = experimentUpdateBody.datasetId - this.datasetVersion = experimentUpdateBody.datasetVersion - this.description = experimentUpdateBody.description - this.metadata = experimentUpdateBody.metadata - this.name = experimentUpdateBody.name - this.public_ = experimentUpdateBody.public_ - this.repoInfo = experimentUpdateBody.repoInfo - additionalProperties(experimentUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + baseExpId = body.baseExpId + datasetId = body.datasetId + datasetVersion = body.datasetVersion + description = body.description + metadata = body.metadata + name = body.name + public_ = body.public_ + repoInfo = body.repoInfo + additionalProperties = body.additionalProperties.toMutableMap() } /** Id of default base experiment to compare against when viewing this experiment */ - @JsonProperty("base_exp_id") - fun baseExpId(baseExpId: String) = apply { this.baseExpId = baseExpId } + fun baseExpId(baseExpId: String?) = baseExpId(JsonField.ofNullable(baseExpId)) + + /** Alias for calling [Builder.baseExpId] with `baseExpId.orElse(null)`. */ + fun baseExpId(baseExpId: Optional) = baseExpId(baseExpId.getOrNull()) + + /** + * Sets [Builder.baseExpId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExpId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baseExpId(baseExpId: JsonField) = apply { this.baseExpId = baseExpId } /** * Identifier of the linked dataset, or null if the experiment is not linked to a * dataset */ - @JsonProperty("dataset_id") - fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } + fun datasetId(datasetId: String?) = datasetId(JsonField.ofNullable(datasetId)) + + /** Alias for calling [Builder.datasetId] with `datasetId.orElse(null)`. */ + fun datasetId(datasetId: Optional) = datasetId(datasetId.getOrNull()) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetId(datasetId: JsonField) = apply { this.datasetId = datasetId } /** * Version number of the linked dataset the experiment was run against. This can be used * to reproduce the experiment after the dataset has been modified. */ - @JsonProperty("dataset_version") - fun datasetVersion(datasetVersion: String) = apply { + fun datasetVersion(datasetVersion: String?) = + datasetVersion(JsonField.ofNullable(datasetVersion)) + + /** Alias for calling [Builder.datasetVersion] with `datasetVersion.orElse(null)`. */ + fun datasetVersion(datasetVersion: Optional) = + datasetVersion(datasetVersion.getOrNull()) + + /** + * Sets [Builder.datasetVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetVersion(datasetVersion: JsonField) = apply { this.datasetVersion = datasetVersion } /** Textual description of the experiment */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** User-controlled metadata about the experiment */ - @JsonProperty("metadata") - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** Name of the experiment. Within a project, experiment names are unique */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization */ - @JsonProperty("public") fun public_(public_: Boolean) = apply { this.public_ = public_ } + fun public_(public_: Boolean?) = public_(JsonField.ofNullable(public_)) + + /** + * Alias for [Builder.public_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun public_(public_: Boolean) = public_(public_ as Boolean?) + + /** Alias for calling [Builder.public_] with `public_.orElse(null)`. */ + fun public_(public_: Optional) = public_(public_.getOrNull()) + + /** + * Sets [Builder.public_] to an arbitrary JSON value. + * + * You should usually call [Builder.public_] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun public_(public_: JsonField) = apply { this.public_ = public_ } /** Metadata about the state of the repo when the experiment was created */ - @JsonProperty("repo_info") - fun repoInfo(repoInfo: RepoInfo) = apply { this.repoInfo = repoInfo } + fun repoInfo(repoInfo: RepoInfo?) = repoInfo(JsonField.ofNullable(repoInfo)) + + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) + + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun repoInfo(repoInfo: JsonField) = apply { this.repoInfo = repoInfo } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ExperimentUpdateBody = - ExperimentUpdateBody( + 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. + */ + fun build(): Body = + Body( baseExpId, datasetId, datasetVersion, @@ -262,264 +573,432 @@ constructor( name, public_, repoInfo, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && baseExpId == other.baseExpId && datasetId == other.datasetId && datasetVersion == other.datasetVersion && description == other.description && metadata == other.metadata && name == other.name && public_ == other.public_ && repoInfo == other.repoInfo && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ExperimentUpdateParams && - this.experimentId == other.experimentId && - this.baseExpId == other.baseExpId && - this.datasetId == other.datasetId && - this.datasetVersion == other.datasetVersion && - this.description == other.description && - this.metadata == other.metadata && - this.name == other.name && - this.public_ == other.public_ && - this.repoInfo == other.repoInfo && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(baseExpId, datasetId, datasetVersion, description, metadata, name, public_, repoInfo, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - experimentId, - baseExpId, - datasetId, - datasetVersion, - description, - metadata, - name, - public_, - repoInfo, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ExperimentUpdateParams{experimentId=$experimentId, baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{baseExpId=$baseExpId, datasetId=$datasetId, datasetVersion=$datasetVersion, description=$description, metadata=$metadata, name=$name, public_=$public_, repoInfo=$repoInfo, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ExperimentUpdateParams]. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ExperimentUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var experimentId: String? = null - private var baseExpId: String? = null - private var datasetId: String? = null - private var datasetVersion: String? = null - private var description: String? = null - private var metadata: Metadata? = null - private var name: String? = null - private var public_: Boolean? = null - private var repoInfo: RepoInfo? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(experimentUpdateParams: ExperimentUpdateParams) = apply { - this.experimentId = experimentUpdateParams.experimentId - this.baseExpId = experimentUpdateParams.baseExpId - this.datasetId = experimentUpdateParams.datasetId - this.datasetVersion = experimentUpdateParams.datasetVersion - this.description = experimentUpdateParams.description - this.metadata = experimentUpdateParams.metadata - this.name = experimentUpdateParams.name - this.public_ = experimentUpdateParams.public_ - this.repoInfo = experimentUpdateParams.repoInfo - additionalQueryParams(experimentUpdateParams.additionalQueryParams) - additionalHeaders(experimentUpdateParams.additionalHeaders) - additionalBodyProperties(experimentUpdateParams.additionalBodyProperties) + experimentId = experimentUpdateParams.experimentId + body = experimentUpdateParams.body.toBuilder() + additionalHeaders = experimentUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = experimentUpdateParams.additionalQueryParams.toBuilder() } /** Experiment id */ fun experimentId(experimentId: String) = apply { this.experimentId = experimentId } /** Id of default base experiment to compare against when viewing this experiment */ - fun baseExpId(baseExpId: String) = apply { this.baseExpId = baseExpId } + fun baseExpId(baseExpId: String?) = apply { body.baseExpId(baseExpId) } + + /** Alias for calling [Builder.baseExpId] with `baseExpId.orElse(null)`. */ + fun baseExpId(baseExpId: Optional) = baseExpId(baseExpId.getOrNull()) + + /** + * Sets [Builder.baseExpId] to an arbitrary JSON value. + * + * You should usually call [Builder.baseExpId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun baseExpId(baseExpId: JsonField) = apply { body.baseExpId(baseExpId) } /** * Identifier of the linked dataset, or null if the experiment is not linked to a dataset */ - fun datasetId(datasetId: String) = apply { this.datasetId = datasetId } + fun datasetId(datasetId: String?) = apply { body.datasetId(datasetId) } + + /** Alias for calling [Builder.datasetId] with `datasetId.orElse(null)`. */ + fun datasetId(datasetId: Optional) = datasetId(datasetId.getOrNull()) + + /** + * Sets [Builder.datasetId] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun datasetId(datasetId: JsonField) = apply { body.datasetId(datasetId) } /** * Version number of the linked dataset the experiment was run against. This can be used to * reproduce the experiment after the dataset has been modified. */ - fun datasetVersion(datasetVersion: String) = apply { this.datasetVersion = datasetVersion } + fun datasetVersion(datasetVersion: String?) = apply { body.datasetVersion(datasetVersion) } + + /** Alias for calling [Builder.datasetVersion] with `datasetVersion.orElse(null)`. */ + fun datasetVersion(datasetVersion: Optional) = + datasetVersion(datasetVersion.getOrNull()) + + /** + * Sets [Builder.datasetVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun datasetVersion(datasetVersion: JsonField) = apply { + body.datasetVersion(datasetVersion) + } /** Textual description of the experiment */ - fun description(description: String) = apply { this.description = description } + 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) } /** User-controlled metadata about the experiment */ - fun metadata(metadata: Metadata) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** Name of the experiment. Within a project, experiment names are unique */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } /** * Whether or not the experiment is public. Public experiments can be viewed by anybody * inside or outside the organization */ - fun public_(public_: Boolean) = apply { this.public_ = public_ } + fun public_(public_: Boolean?) = apply { body.public_(public_) } + + /** + * Alias for [Builder.public_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun public_(public_: Boolean) = public_(public_ as Boolean?) + + /** Alias for calling [Builder.public_] with `public_.orElse(null)`. */ + fun public_(public_: Optional) = public_(public_.getOrNull()) + + /** + * Sets [Builder.public_] to an arbitrary JSON value. + * + * You should usually call [Builder.public_] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun public_(public_: JsonField) = apply { body.public_(public_) } /** Metadata about the state of the repo when the experiment was created */ - fun repoInfo(repoInfo: RepoInfo) = apply { this.repoInfo = repoInfo } + fun repoInfo(repoInfo: RepoInfo?) = apply { body.repoInfo(repoInfo) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.repoInfo] with `repoInfo.orElse(null)`. */ + fun repoInfo(repoInfo: Optional) = repoInfo(repoInfo.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.repoInfo] to an arbitrary JSON value. + * + * You should usually call [Builder.repoInfo] with a well-typed [RepoInfo] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun repoInfo(repoInfo: JsonField) = apply { body.repoInfo(repoInfo) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ExperimentUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ExperimentUpdateParams = ExperimentUpdateParams( - checkNotNull(experimentId) { "`experimentId` is required but was not set" }, - baseExpId, - datasetId, - datasetVersion, - description, - metadata, - name, - public_, - repoInfo, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("experimentId", experimentId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } /** User-controlled metadata about the experiment */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ExperimentUpdateParams && experimentId == other.experimentId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(experimentId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ExperimentUpdateParams{experimentId=$experimentId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackDatasetItem.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackDatasetItem.kt index 7e931a63..363314e1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackDatasetItem.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackDatasetItem.kt @@ -8,133 +8,169 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FeedbackDatasetItem.Builder::class) @NoAutoDetect class FeedbackDatasetItem +@JsonCreator private constructor( - private val id: JsonField, - private val comment: JsonField, - private val metadata: JsonField, - private val source: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("comment") + @ExcludeMissing + private val comment: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + private val source: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * The id of the dataset event to log feedback for. This is the row `id` returned by `POST * /v1/dataset/{dataset_id}/insert` + * + * @throws BraintrustInvalidDataException 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") - /** An optional comment string to log about the dataset event */ + /** + * An optional comment string to log about the dataset event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun comment(): Optional = Optional.ofNullable(comment.getNullable("comment")) /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + /** + * The source of the feedback. Must be one of "external" (default), "app", or "api" + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun source(): Optional = Optional.ofNullable(source.getNullable("source")) /** - * The id of the dataset event to log feedback for. This is the row `id` returned by `POST - * /v1/dataset/{dataset_id}/insert` + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** An optional comment string to log about the dataset event */ - @JsonProperty("comment") @ExcludeMissing fun _comment() = comment + /** + * 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 /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * Returns the raw JSON value of [comment]. + * + * Unlike [comment], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("comment") @ExcludeMissing fun _comment(): JsonField = comment - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") @ExcludeMissing fun _source() = source + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [source]. + * + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FeedbackDatasetItem = apply { - if (!validated) { - id() - comment() - metadata().map { it.validate() } - source() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FeedbackDatasetItem = apply { + if (validated) { + return@apply } - return other is FeedbackDatasetItem && - this.id == other.id && - this.comment == other.comment && - this.metadata == other.metadata && - this.source == other.source && - this.additionalProperties == other.additionalProperties + id() + comment() + metadata().ifPresent { it.validate() } + source() + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - comment, - metadata, - source, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "FeedbackDatasetItem{id=$id, comment=$comment, metadata=$metadata, source=$source, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FeedbackDatasetItem]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FeedbackDatasetItem]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() + private var id: JsonField? = null private var comment: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() private var source: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(feedbackDatasetItem: FeedbackDatasetItem) = apply { - this.id = feedbackDatasetItem.id - this.comment = feedbackDatasetItem.comment - this.metadata = feedbackDatasetItem.metadata - this.source = feedbackDatasetItem.source - additionalProperties(feedbackDatasetItem.additionalProperties) + id = feedbackDatasetItem.id + comment = feedbackDatasetItem.comment + metadata = feedbackDatasetItem.metadata + source = feedbackDatasetItem.source + tags = feedbackDatasetItem.tags.map { it.toMutableList() } + additionalProperties = feedbackDatasetItem.additionalProperties.toMutableMap() } /** @@ -144,185 +180,272 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * The id of the dataset event to log feedback for. This is the row `id` returned by `POST - * /v1/dataset/{dataset_id}/insert` + * 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. */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } + fun id(id: JsonField) = apply { this.id = id } /** An optional comment string to log about the dataset event */ - fun comment(comment: String) = comment(JsonField.of(comment)) + fun comment(comment: String?) = comment(JsonField.ofNullable(comment)) - /** An optional comment string to log about the dataset event */ - @JsonProperty("comment") - @ExcludeMissing + /** Alias for calling [Builder.comment] with `comment.orElse(null)`. */ + fun comment(comment: Optional) = comment(comment.getOrNull()) + + /** + * Sets [Builder.comment] to an arbitrary JSON value. + * + * You should usually call [Builder.comment] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun comment(comment: JsonField) = apply { this.comment = comment } /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * log it here and access it in the Braintrust UI. Note, this metadata does not correspond + * to the main event itself, but rather the audit log attached to the event. */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("metadata") - @ExcludeMissing fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - fun source(source: Source) = source(JsonField.of(source)) + fun source(source: Source?) = source(JsonField.ofNullable(source)) - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") - @ExcludeMissing + /** Alias for calling [Builder.source] with `source.orElse(null)`. */ + fun source(source: Optional) = source(source.getOrNull()) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [Source] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun source(source: JsonField) = apply { this.source = source } + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FeedbackDatasetItem]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FeedbackDatasetItem = FeedbackDatasetItem( - id, + checkRequired("id", id), comment, metadata, source, - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class Source - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Source && this.value == other.value + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + class Source @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 APP = Source(JsonField.of("app")) + @JvmField val APP = of("app") - @JvmField val API = Source(JsonField.of("api")) + @JvmField val API = of("api") - @JvmField val EXTERNAL = Source(JsonField.of("external")) + @JvmField val EXTERNAL = of("external") @JvmStatic fun of(value: String) = Source(JsonField.of(value)) } + /** An enum containing [Source]'s known values. */ enum class Known { APP, API, EXTERNAL, } + /** + * An enum containing [Source]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Source] 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 { APP, API, EXTERNAL, + /** An enum member indicating that [Source] 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) { APP -> Value.APP @@ -331,6 +454,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { APP -> Known.APP @@ -339,6 +471,47 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown Source: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Source && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FeedbackDatasetItem && id == other.id && comment == other.comment && metadata == other.metadata && source == other.source && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, comment, metadata, source, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FeedbackDatasetItem{id=$id, comment=$comment, metadata=$metadata, source=$source, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackExperimentItem.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackExperimentItem.kt index 2abcfe43..406a2fd1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackExperimentItem.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackExperimentItem.kt @@ -8,169 +8,200 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FeedbackExperimentItem.Builder::class) @NoAutoDetect class FeedbackExperimentItem +@JsonCreator private constructor( - private val id: JsonField, - private val scores: JsonField, - private val expected: JsonValue, - private val comment: JsonField, - private val metadata: JsonField, - private val source: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("comment") + @ExcludeMissing + private val comment: JsonField = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + private val source: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * The id of the experiment event to log feedback for. This is the row `id` returned by `POST * /v1/experiment/{experiment_id}/insert` + * + * @throws BraintrustInvalidDataException 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") /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the - * existing scores for the experiment event + * An optional comment string to log about the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + fun comment(): Optional = Optional.ofNullable(comment.getNullable("comment")) /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to * `output` to determine if your `output` value is correct or not */ - fun expected(): JsonValue = expected - - /** An optional comment string to log about the experiment event */ - fun comment(): Optional = Optional.ofNullable(comment.getNullable("comment")) + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + /** + * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the + * existing scores for the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + + /** + * The source of the feedback. Must be one of "external" (default), "app", or "api" + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun source(): Optional = Optional.ofNullable(source.getNullable("source")) /** - * The id of the experiment event to log feedback for. This is the row `id` returned by `POST - * /v1/experiment/{experiment_id}/insert` + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the - * existing scores for the experiment event + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not + * Returns the raw JSON value of [comment]. + * + * Unlike [comment], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected + @JsonProperty("comment") @ExcludeMissing fun _comment(): JsonField = comment - /** An optional comment string to log about the experiment event */ - @JsonProperty("comment") @ExcludeMissing fun _comment() = comment + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") @ExcludeMissing fun _source() = source + /** + * Returns the raw JSON value of [source]. + * + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FeedbackExperimentItem = apply { - if (!validated) { - id() - scores().map { it.validate() } - expected() - comment() - metadata().map { it.validate() } - source() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FeedbackExperimentItem = apply { + if (validated) { + return@apply } - return other is FeedbackExperimentItem && - this.id == other.id && - this.scores == other.scores && - this.expected == other.expected && - this.comment == other.comment && - this.metadata == other.metadata && - this.source == other.source && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - scores, - expected, - comment, - metadata, - source, - additionalProperties, - ) - } - return hashCode + id() + comment() + metadata().ifPresent { it.validate() } + scores().ifPresent { it.validate() } + source() + tags() + validated = true } - override fun toString() = - "FeedbackExperimentItem{id=$id, scores=$scores, expected=$expected, comment=$comment, metadata=$metadata, source=$source, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FeedbackExperimentItem]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FeedbackExperimentItem]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() + private var id: JsonField? = null private var comment: JsonField = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() private var source: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(feedbackExperimentItem: FeedbackExperimentItem) = apply { - this.id = feedbackExperimentItem.id - this.scores = feedbackExperimentItem.scores - this.expected = feedbackExperimentItem.expected - this.comment = feedbackExperimentItem.comment - this.metadata = feedbackExperimentItem.metadata - this.source = feedbackExperimentItem.source - additionalProperties(feedbackExperimentItem.additionalProperties) + id = feedbackExperimentItem.id + comment = feedbackExperimentItem.comment + expected = feedbackExperimentItem.expected + metadata = feedbackExperimentItem.metadata + scores = feedbackExperimentItem.scores + source = feedbackExperimentItem.source + tags = feedbackExperimentItem.tags.map { it.toMutableList() } + additionalProperties = feedbackExperimentItem.additionalProperties.toMutableMap() } /** @@ -180,285 +211,385 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * The id of the experiment event to log feedback for. This is the row `id` returned by - * `POST /v1/experiment/{experiment_id}/insert` + * 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. */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } + fun id(id: JsonField) = apply { this.id = id } - /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into - * the existing scores for the experiment event - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) + /** An optional comment string to log about the experiment event */ + fun comment(comment: String?) = comment(JsonField.ofNullable(comment)) + + /** Alias for calling [Builder.comment] with `comment.orElse(null)`. */ + fun comment(comment: Optional) = comment(comment.getOrNull()) /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into - * the existing scores for the experiment event + * Sets [Builder.comment] to an arbitrary JSON value. + * + * You should usually call [Builder.comment] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } + fun comment(comment: JsonField) = apply { this.comment = comment } /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to * `output` to determine if your `output` value is correct or not */ - @JsonProperty("expected") - @ExcludeMissing fun expected(expected: JsonValue) = apply { this.expected = expected } - /** An optional comment string to log about the experiment event */ - fun comment(comment: String) = comment(JsonField.of(comment)) - - /** An optional comment string to log about the experiment event */ - @JsonProperty("comment") - @ExcludeMissing - fun comment(comment: JsonField) = apply { this.comment = comment } - /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * log it here and access it in the Braintrust UI. Note, this metadata does not correspond + * to the main event itself, but rather the audit log attached to the event. */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("metadata") - @ExcludeMissing fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - fun source(source: Source) = source(JsonField.of(source)) + /** + * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into + * the existing scores for the experiment event + */ + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") - @ExcludeMissing + fun source(source: Source?) = source(JsonField.ofNullable(source)) + + /** Alias for calling [Builder.source] with `source.orElse(null)`. */ + fun source(source: Optional) = source(source.getOrNull()) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [Source] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun source(source: JsonField) = apply { this.source = source } + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FeedbackExperimentItem]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FeedbackExperimentItem = FeedbackExperimentItem( - id, - scores, - expected, + checkRequired("id", id), comment, + expected, metadata, + scores, source, - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } /** * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the * existing scores for the experiment event */ - @JsonDeserialize(builder = Scores.Builder::class) @NoAutoDetect class Scores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Scores = apply { + if (validated) { + return@apply } - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Scores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Scores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Scores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) + additionalProperties = scores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class Source - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Source && this.value == other.value + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } + + /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + class Source @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 APP = Source(JsonField.of("app")) + @JvmField val APP = of("app") - @JvmField val API = Source(JsonField.of("api")) + @JvmField val API = of("api") - @JvmField val EXTERNAL = Source(JsonField.of("external")) + @JvmField val EXTERNAL = of("external") @JvmStatic fun of(value: String) = Source(JsonField.of(value)) } + /** An enum containing [Source]'s known values. */ enum class Known { APP, API, EXTERNAL, } + /** + * An enum containing [Source]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Source] 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 { APP, API, EXTERNAL, + /** An enum member indicating that [Source] 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) { APP -> Value.APP @@ -467,6 +598,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { APP -> Known.APP @@ -475,6 +615,47 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown Source: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Source && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FeedbackExperimentItem && id == other.id && comment == other.comment && expected == other.expected && metadata == other.metadata && scores == other.scores && source == other.source && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, comment, expected, metadata, scores, source, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FeedbackExperimentItem{id=$id, comment=$comment, expected=$expected, metadata=$metadata, scores=$scores, source=$source, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItem.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItem.kt index becc2347..3741b996 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItem.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItem.kt @@ -8,169 +8,200 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FeedbackProjectLogsItem.Builder::class) @NoAutoDetect class FeedbackProjectLogsItem +@JsonCreator private constructor( - private val id: JsonField, - private val scores: JsonField, - private val expected: JsonValue, - private val comment: JsonField, - private val metadata: JsonField, - private val source: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("comment") + @ExcludeMissing + private val comment: JsonField = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("source") + @ExcludeMissing + private val source: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * The id of the project logs event to log feedback for. This is the row `id` returned by `POST * /v1/project_logs/{project_id}/insert` + * + * @throws BraintrustInvalidDataException 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") /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the - * existing scores for the project logs event + * An optional comment string to log about the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + fun comment(): Optional = Optional.ofNullable(comment.getNullable("comment")) /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to * `output` to determine if your `output` value is correct or not */ - fun expected(): JsonValue = expected - - /** An optional comment string to log about the project logs event */ - fun comment(): Optional = Optional.ofNullable(comment.getNullable("comment")) + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + /** + * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the + * existing scores for the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + + /** + * The source of the feedback. Must be one of "external" (default), "app", or "api" + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun source(): Optional = Optional.ofNullable(source.getNullable("source")) /** - * The id of the project logs event to log feedback for. This is the row `id` returned by `POST - * /v1/project_logs/{project_id}/insert` + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the - * existing scores for the project logs event + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not + * Returns the raw JSON value of [comment]. + * + * Unlike [comment], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected + @JsonProperty("comment") @ExcludeMissing fun _comment(): JsonField = comment - /** An optional comment string to log about the project logs event */ - @JsonProperty("comment") @ExcludeMissing fun _comment() = comment + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") @ExcludeMissing fun _source() = source + /** + * Returns the raw JSON value of [source]. + * + * Unlike [source], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("source") @ExcludeMissing fun _source(): JsonField = source + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FeedbackProjectLogsItem = apply { - if (!validated) { - id() - scores().map { it.validate() } - expected() - comment() - metadata().map { it.validate() } - source() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FeedbackProjectLogsItem = apply { + if (validated) { + return@apply } - return other is FeedbackProjectLogsItem && - this.id == other.id && - this.scores == other.scores && - this.expected == other.expected && - this.comment == other.comment && - this.metadata == other.metadata && - this.source == other.source && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - scores, - expected, - comment, - metadata, - source, - additionalProperties, - ) - } - return hashCode + id() + comment() + metadata().ifPresent { it.validate() } + scores().ifPresent { it.validate() } + source() + tags() + validated = true } - override fun toString() = - "FeedbackProjectLogsItem{id=$id, scores=$scores, expected=$expected, comment=$comment, metadata=$metadata, source=$source, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FeedbackProjectLogsItem]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FeedbackProjectLogsItem]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() + private var id: JsonField? = null private var comment: JsonField = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() private var source: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(feedbackProjectLogsItem: FeedbackProjectLogsItem) = apply { - this.id = feedbackProjectLogsItem.id - this.scores = feedbackProjectLogsItem.scores - this.expected = feedbackProjectLogsItem.expected - this.comment = feedbackProjectLogsItem.comment - this.metadata = feedbackProjectLogsItem.metadata - this.source = feedbackProjectLogsItem.source - additionalProperties(feedbackProjectLogsItem.additionalProperties) + id = feedbackProjectLogsItem.id + comment = feedbackProjectLogsItem.comment + expected = feedbackProjectLogsItem.expected + metadata = feedbackProjectLogsItem.metadata + scores = feedbackProjectLogsItem.scores + source = feedbackProjectLogsItem.source + tags = feedbackProjectLogsItem.tags.map { it.toMutableList() } + additionalProperties = feedbackProjectLogsItem.additionalProperties.toMutableMap() } /** @@ -180,285 +211,385 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * The id of the project logs event to log feedback for. This is the row `id` returned by - * `POST /v1/project_logs/{project_id}/insert` + * 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. */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } + fun id(id: JsonField) = apply { this.id = id } - /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into - * the existing scores for the project logs event - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) + /** An optional comment string to log about the project logs event */ + fun comment(comment: String?) = comment(JsonField.ofNullable(comment)) + + /** Alias for calling [Builder.comment] with `comment.orElse(null)`. */ + fun comment(comment: Optional) = comment(comment.getOrNull()) /** - * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into - * the existing scores for the project logs event + * Sets [Builder.comment] to an arbitrary JSON value. + * + * You should usually call [Builder.comment] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } + fun comment(comment: JsonField) = apply { this.comment = comment } /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to * `output` to determine if your `output` value is correct or not */ - @JsonProperty("expected") - @ExcludeMissing fun expected(expected: JsonValue) = apply { this.expected = expected } - /** An optional comment string to log about the project logs event */ - fun comment(comment: String) = comment(JsonField.of(comment)) - - /** An optional comment string to log about the project logs event */ - @JsonProperty("comment") - @ExcludeMissing - fun comment(comment: JsonField) = apply { this.comment = comment } - /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * log it here and access it in the Braintrust UI. Note, this metadata does not correspond + * to the main event itself, but rather the audit log attached to the event. */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) /** - * A dictionary with additional data about the feedback. If you have a `user_id`, you can - * log it here and access it in the Braintrust UI. + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. */ - @JsonProperty("metadata") - @ExcludeMissing fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - fun source(source: Source) = source(JsonField.of(source)) + /** + * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into + * the existing scores for the project logs event + */ + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ - @JsonProperty("source") - @ExcludeMissing + fun source(source: Source?) = source(JsonField.ofNullable(source)) + + /** Alias for calling [Builder.source] with `source.orElse(null)`. */ + fun source(source: Optional) = source(source.getOrNull()) + + /** + * Sets [Builder.source] to an arbitrary JSON value. + * + * You should usually call [Builder.source] with a well-typed [Source] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun source(source: JsonField) = apply { this.source = source } + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FeedbackProjectLogsItem]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FeedbackProjectLogsItem = FeedbackProjectLogsItem( - id, - scores, - expected, + checkRequired("id", id), comment, + expected, metadata, + scores, source, - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } /** * A dictionary with additional data about the feedback. If you have a `user_id`, you can log it - * here and access it in the Braintrust UI. + * here and access it in the Braintrust UI. Note, this metadata does not correspond to the main + * event itself, but rather the audit log attached to the event. */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } /** * A dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the * existing scores for the project logs event */ - @JsonDeserialize(builder = Scores.Builder::class) @NoAutoDetect class Scores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Scores = apply { + if (validated) { + return@apply } - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Scores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Scores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Scores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) + additionalProperties = scores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class Source - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Source && this.value == other.value + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } + + /** The source of the feedback. Must be one of "external" (default), "app", or "api" */ + class Source @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 APP = Source(JsonField.of("app")) + @JvmField val APP = of("app") - @JvmField val API = Source(JsonField.of("api")) + @JvmField val API = of("api") - @JvmField val EXTERNAL = Source(JsonField.of("external")) + @JvmField val EXTERNAL = of("external") @JvmStatic fun of(value: String) = Source(JsonField.of(value)) } + /** An enum containing [Source]'s known values. */ enum class Known { APP, API, EXTERNAL, } + /** + * An enum containing [Source]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Source] 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 { APP, API, EXTERNAL, + /** An enum member indicating that [Source] 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) { APP -> Value.APP @@ -467,6 +598,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { APP -> Known.APP @@ -475,6 +615,47 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown Source: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Source && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FeedbackProjectLogsItem && id == other.id && comment == other.comment && expected == other.expected && metadata == other.metadata && scores == other.scores && source == other.source && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, comment, expected, metadata, scores, source, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FeedbackProjectLogsItem{id=$id, comment=$comment, expected=$expected, metadata=$metadata, scores=$scores, source=$source, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackResponseSchema.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackResponseSchema.kt index a3654dac..8bbcb0f7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackResponseSchema.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FeedbackResponseSchema.kt @@ -8,152 +8,237 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects -@JsonDeserialize(builder = FeedbackResponseSchema.Builder::class) @NoAutoDetect class FeedbackResponseSchema +@JsonCreator private constructor( - private val status: JsonField, - private val additionalProperties: Map, + @JsonProperty("status") + @ExcludeMissing + private val status: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 status(): Status = status.getRequired("status") - @JsonProperty("status") @ExcludeMissing fun _status() = status + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FeedbackResponseSchema = apply { - if (!validated) { - status() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FeedbackResponseSchema = apply { + if (validated) { + return@apply } - return other is FeedbackResponseSchema && - this.status == other.status && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(status, additionalProperties) - } - return hashCode + status() + validated = true } - override fun toString() = - "FeedbackResponseSchema{status=$status, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FeedbackResponseSchema]. + * + * The following fields are required: + * ```java + * .status() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FeedbackResponseSchema]. */ + class Builder internal constructor() { - private var status: JsonField = JsonMissing.of() + private var status: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(feedbackResponseSchema: FeedbackResponseSchema) = apply { - this.status = feedbackResponseSchema.status - additionalProperties(feedbackResponseSchema.additionalProperties) + status = feedbackResponseSchema.status + additionalProperties = feedbackResponseSchema.additionalProperties.toMutableMap() } fun status(status: Status) = status(JsonField.of(status)) - @JsonProperty("status") - @ExcludeMissing + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun status(status: JsonField) = apply { this.status = status } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FeedbackResponseSchema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FeedbackResponseSchema = - FeedbackResponseSchema(status, additionalProperties.toUnmodifiable()) + FeedbackResponseSchema( + checkRequired("status", status), + additionalProperties.toImmutable(), + ) } - class Status - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + class Status @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Status && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val SUCCESS = Status(JsonField.of("success")) + @JvmField val SUCCESS = of("success") @JvmStatic fun of(value: String) = Status(JsonField.of(value)) } + /** An enum containing [Status]'s known values. */ enum class Known { - SUCCESS, + SUCCESS } + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] 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 { SUCCESS, + /** An enum member indicating that [Status] 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) { SUCCESS -> Value.SUCCESS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { SUCCESS -> Known.SUCCESS else -> throw BraintrustInvalidDataException("Unknown Status: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Status && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FeedbackResponseSchema && status == other.status && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(status, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FeedbackResponseSchema{status=$status, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponse.kt index 00a47268..627d9ef7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponse.kt @@ -7,28 +7,38 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FetchDatasetEventsResponse.Builder::class) @NoAutoDetect class FetchDatasetEventsResponse +@JsonCreator private constructor( - private val events: JsonField>, - private val cursor: JsonField, - private val additionalProperties: Map, + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** A list of fetched events */ + /** + * A list of fetched events + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") /** @@ -36,93 +46,96 @@ private constructor( * * Pass this string directly as the `cursor` param to your next fetch request to get the next * page of results. Not provided if the returned result set is empty. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) - /** A list of fetched events */ - @JsonProperty("events") @ExcludeMissing fun _events() = events + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") @ExcludeMissing fun _events(): JsonField> = events /** - * Pagination cursor + * Returns the raw JSON value of [cursor]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the next - * page of results. Not provided if the returned result set is empty. + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("cursor") @ExcludeMissing fun _cursor() = cursor + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FetchDatasetEventsResponse = apply { - if (!validated) { - events().forEach { it.validate() } - cursor() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FetchDatasetEventsResponse = apply { + if (validated) { + return@apply } - return other is FetchDatasetEventsResponse && - this.events == other.events && - this.cursor == other.cursor && - this.additionalProperties == other.additionalProperties + events().forEach { it.validate() } + cursor() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - events, - cursor, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "FetchDatasetEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FetchDatasetEventsResponse]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FetchDatasetEventsResponse]. */ + class Builder internal constructor() { - private var events: JsonField> = JsonMissing.of() + private var events: JsonField>? = null private var cursor: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(fetchDatasetEventsResponse: FetchDatasetEventsResponse) = apply { - this.events = fetchDatasetEventsResponse.events - this.cursor = fetchDatasetEventsResponse.cursor - additionalProperties(fetchDatasetEventsResponse.additionalProperties) + events = fetchDatasetEventsResponse.events.map { it.toMutableList() } + cursor = fetchDatasetEventsResponse.cursor + additionalProperties = fetchDatasetEventsResponse.additionalProperties.toMutableMap() } /** A list of fetched events */ fun events(events: List) = events(JsonField.of(events)) - /** A list of fetched events */ - @JsonProperty("events") - @ExcludeMissing - fun events(events: JsonField>) = apply { this.events = events } + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } /** - * Pagination cursor + * Adds a single [DatasetEvent] to [events]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the - * next page of results. Not provided if the returned result set is empty. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun cursor(cursor: String) = cursor(JsonField.of(cursor)) + fun addEvent(event: DatasetEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } /** * Pagination cursor @@ -130,29 +143,72 @@ private constructor( * Pass this string directly as the `cursor` param to your next fetch request to get the * next page of results. Not provided if the returned result set is empty. */ - @JsonProperty("cursor") - @ExcludeMissing + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** + * Sets [Builder.cursor] to an arbitrary JSON value. + * + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun cursor(cursor: JsonField) = apply { this.cursor = cursor } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FetchDatasetEventsResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FetchDatasetEventsResponse = FetchDatasetEventsResponse( - events.map { it.toUnmodifiable() }, + checkRequired("events", events).map { it.toImmutable() }, cursor, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FetchDatasetEventsResponse && events == other.events && cursor == other.cursor && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, cursor, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FetchDatasetEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponse.kt index 318e1c7a..585ff788 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponse.kt @@ -7,28 +7,38 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FetchExperimentEventsResponse.Builder::class) @NoAutoDetect class FetchExperimentEventsResponse +@JsonCreator private constructor( - private val events: JsonField>, - private val cursor: JsonField, - private val additionalProperties: Map, + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** A list of fetched events */ + /** + * A list of fetched events + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") /** @@ -36,93 +46,97 @@ private constructor( * * Pass this string directly as the `cursor` param to your next fetch request to get the next * page of results. Not provided if the returned result set is empty. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) - /** A list of fetched events */ - @JsonProperty("events") @ExcludeMissing fun _events() = events + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") @ExcludeMissing fun _events(): JsonField> = events /** - * Pagination cursor + * Returns the raw JSON value of [cursor]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the next - * page of results. Not provided if the returned result set is empty. + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("cursor") @ExcludeMissing fun _cursor() = cursor + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FetchExperimentEventsResponse = apply { - if (!validated) { - events().forEach { it.validate() } - cursor() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FetchExperimentEventsResponse = apply { + if (validated) { + return@apply } - return other is FetchExperimentEventsResponse && - this.events == other.events && - this.cursor == other.cursor && - this.additionalProperties == other.additionalProperties + events().forEach { it.validate() } + cursor() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - events, - cursor, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "FetchExperimentEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [FetchExperimentEventsResponse]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FetchExperimentEventsResponse]. */ + class Builder internal constructor() { - private var events: JsonField> = JsonMissing.of() + private var events: JsonField>? = null private var cursor: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(fetchExperimentEventsResponse: FetchExperimentEventsResponse) = apply { - this.events = fetchExperimentEventsResponse.events - this.cursor = fetchExperimentEventsResponse.cursor - additionalProperties(fetchExperimentEventsResponse.additionalProperties) + events = fetchExperimentEventsResponse.events.map { it.toMutableList() } + cursor = fetchExperimentEventsResponse.cursor + additionalProperties = fetchExperimentEventsResponse.additionalProperties.toMutableMap() } /** A list of fetched events */ fun events(events: List) = events(JsonField.of(events)) - /** A list of fetched events */ - @JsonProperty("events") - @ExcludeMissing - fun events(events: JsonField>) = apply { this.events = events } + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } /** - * Pagination cursor + * Adds a single [ExperimentEvent] to [events]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the - * next page of results. Not provided if the returned result set is empty. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun cursor(cursor: String) = cursor(JsonField.of(cursor)) + fun addEvent(event: ExperimentEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } /** * Pagination cursor @@ -130,29 +144,72 @@ private constructor( * Pass this string directly as the `cursor` param to your next fetch request to get the * next page of results. Not provided if the returned result set is empty. */ - @JsonProperty("cursor") - @ExcludeMissing + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** + * Sets [Builder.cursor] to an arbitrary JSON value. + * + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun cursor(cursor: JsonField) = apply { this.cursor = cursor } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FetchExperimentEventsResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FetchExperimentEventsResponse = FetchExperimentEventsResponse( - events.map { it.toUnmodifiable() }, + checkRequired("events", events).map { it.toImmutable() }, cursor, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FetchExperimentEventsResponse && events == other.events && cursor == other.cursor && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, cursor, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FetchExperimentEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponse.kt index 7c808c80..81de5770 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponse.kt @@ -7,28 +7,38 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = FetchProjectLogsEventsResponse.Builder::class) @NoAutoDetect class FetchProjectLogsEventsResponse +@JsonCreator private constructor( - private val events: JsonField>, - private val cursor: JsonField, - private val additionalProperties: Map, + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** A list of fetched events */ + /** + * A list of fetched events + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") /** @@ -36,93 +46,100 @@ private constructor( * * Pass this string directly as the `cursor` param to your next fetch request to get the next * page of results. Not provided if the returned result set is empty. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) - /** A list of fetched events */ - @JsonProperty("events") @ExcludeMissing fun _events() = events + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") + @ExcludeMissing + fun _events(): JsonField> = events /** - * Pagination cursor + * Returns the raw JSON value of [cursor]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the next - * page of results. Not provided if the returned result set is empty. + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("cursor") @ExcludeMissing fun _cursor() = cursor + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FetchProjectLogsEventsResponse = apply { - if (!validated) { - events().forEach { it.validate() } - cursor() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FetchProjectLogsEventsResponse = apply { + if (validated) { + return@apply } - return other is FetchProjectLogsEventsResponse && - this.events == other.events && - this.cursor == other.cursor && - this.additionalProperties == other.additionalProperties + events().forEach { it.validate() } + cursor() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - events, - cursor, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "FetchProjectLogsEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [FetchProjectLogsEventsResponse]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FetchProjectLogsEventsResponse]. */ + class Builder internal constructor() { - private var events: JsonField> = JsonMissing.of() + private var events: JsonField>? = null private var cursor: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(fetchProjectLogsEventsResponse: FetchProjectLogsEventsResponse) = apply { - this.events = fetchProjectLogsEventsResponse.events - this.cursor = fetchProjectLogsEventsResponse.cursor - additionalProperties(fetchProjectLogsEventsResponse.additionalProperties) + events = fetchProjectLogsEventsResponse.events.map { it.toMutableList() } + cursor = fetchProjectLogsEventsResponse.cursor + additionalProperties = + fetchProjectLogsEventsResponse.additionalProperties.toMutableMap() } /** A list of fetched events */ fun events(events: List) = events(JsonField.of(events)) - /** A list of fetched events */ - @JsonProperty("events") - @ExcludeMissing - fun events(events: JsonField>) = apply { this.events = events } + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } /** - * Pagination cursor + * Adds a single [ProjectLogsEvent] to [events]. * - * Pass this string directly as the `cursor` param to your next fetch request to get the - * next page of results. Not provided if the returned result set is empty. + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun cursor(cursor: String) = cursor(JsonField.of(cursor)) + fun addEvent(event: ProjectLogsEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } /** * Pagination cursor @@ -130,29 +147,72 @@ private constructor( * Pass this string directly as the `cursor` param to your next fetch request to get the * next page of results. Not provided if the returned result set is empty. */ - @JsonProperty("cursor") - @ExcludeMissing + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) + + /** + * Sets [Builder.cursor] to an arbitrary JSON value. + * + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun cursor(cursor: JsonField) = apply { this.cursor = cursor } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FetchProjectLogsEventsResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FetchProjectLogsEventsResponse = FetchProjectLogsEventsResponse( - events.map { it.toUnmodifiable() }, + checkRequired("events", events).map { it.toImmutable() }, cursor, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FetchProjectLogsEventsResponse && events == other.events && cursor == other.cursor && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, cursor, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FetchProjectLogsEventsResponse{events=$events, cursor=$cursor, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Function.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Function.kt index 54481c03..9811c9a5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Function.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Function.kt @@ -10,8 +10,11 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -27,269 +30,405 @@ import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function +@JsonCreator private constructor( - private val id: JsonField, - private val _xactId: JsonField, - private val projectId: JsonField, - private val logId: JsonField, - private val orgId: JsonField, - private val name: JsonField, - private val slug: JsonField, - private val description: JsonField, - private val created: JsonField, - private val promptData: JsonField, - private val tags: JsonField>, - private val metadata: JsonField, - private val functionType: JsonField, - private val functionData: JsonField, - private val origin: JsonField, - private val functionSchema: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("function_data") + @ExcludeMissing + private val functionData: JsonField = JsonMissing.of(), + @JsonProperty("log_id") @ExcludeMissing private val logId: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") @ExcludeMissing private val slug: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_schema") + @ExcludeMissing + private val functionSchema: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the prompt */ + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 transaction id of an event is unique to the network operation that processed the event * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve * a versioned snapshot of the prompt (see the `version` parameter) + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") - /** Unique identifier for the project that the prompt belongs under */ - fun projectId(): String = projectId.getRequired("project_id") + /** + * @throws BraintrustInvalidDataException 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 functionData(): FunctionData = functionData.getRequired("function_data") - /** A literal 'p' which identifies the object as a project prompt */ + /** + * A literal 'p' which identifies the object as a project prompt + * + * @throws BraintrustInvalidDataException 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 logId(): LogId = logId.getRequired("log_id") - /** Unique identifier for the organization */ + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") - /** Name of the prompt */ - fun name(): String = name.getRequired("name") + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the prompt */ + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") - /** Textual description of the prompt */ - fun description(): Optional = - Optional.ofNullable(description.getNullable("description")) - - /** Date of prompt creation */ + /** + * Date of prompt creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** The prompt, model, and its parameters */ - fun promptData(): Optional = - Optional.ofNullable(promptData.getNullable("prompt_data")) - - /** A list of tags for the prompt */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** User-controlled metadata about the prompt */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + /** + * JSON schema for the function's parameters and return type + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionSchema(): Optional = + Optional.ofNullable(functionSchema.getNullable("function_schema")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun functionType(): Optional = Optional.ofNullable(functionType.getNullable("function_type")) - fun functionData(): FunctionData = functionData.getRequired("function_data") + /** + * User-controlled metadata about the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) - /** JSON schema for the function's parameters and return type */ - fun functionSchema(): Optional = - Optional.ofNullable(functionSchema.getNullable("function_schema")) + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) - /** Unique identifier for the prompt */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) /** - * The transaction id of an event is unique to the network operation that processed the event - * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve - * a versioned snapshot of the prompt (see the `version` parameter) + * 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 [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("_xact_id") @ExcludeMissing fun __xactId() = _xactId + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Returns the raw JSON value of [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("function_data") + @ExcludeMissing + fun _functionData(): JsonField = functionData - /** A literal 'p' which identifies the object as a project prompt */ - @JsonProperty("log_id") @ExcludeMissing fun _logId() = logId + /** + * Returns the raw JSON value of [logId]. + * + * Unlike [logId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("log_id") @ExcludeMissing fun _logId(): JsonField = logId - /** Unique identifier for the organization */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + /** + * 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 - /** Name of the prompt */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId - /** Unique identifier for the prompt */ - @JsonProperty("slug") @ExcludeMissing fun _slug() = slug + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId - /** Textual description of the prompt */ - @JsonProperty("description") @ExcludeMissing fun _description() = description + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug - /** Date of prompt creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") @ExcludeMissing fun _promptData() = promptData + /** + * 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 - /** A list of tags for the prompt */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags + /** + * Returns the raw JSON value of [functionSchema]. + * + * Unlike [functionSchema], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("function_schema") + @ExcludeMissing + fun _functionSchema(): JsonField = functionSchema - /** User-controlled metadata about the prompt */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType - @JsonProperty("function_type") @ExcludeMissing fun _functionType() = functionType + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata - @JsonProperty("function_data") @ExcludeMissing fun _functionData() = functionData + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin - @JsonProperty("origin") @ExcludeMissing fun _origin() = origin + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData - /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") @ExcludeMissing fun _functionSchema() = functionSchema + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - id() - _xactId() - projectId() - logId() - orgId() - name() - slug() - description() - created() - promptData().map { it.validate() } - tags() - metadata().map { it.validate() } - functionType() - functionData() - origin().map { it.validate() } - functionSchema().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.id == other.id && - this._xactId == other._xactId && - this.projectId == other.projectId && - this.logId == other.logId && - this.orgId == other.orgId && - this.name == other.name && - this.slug == other.slug && - this.description == other.description && - this.created == other.created && - this.promptData == other.promptData && - this.tags == other.tags && - this.metadata == other.metadata && - this.functionType == other.functionType && - this.functionData == other.functionData && - this.origin == other.origin && - this.functionSchema == other.functionSchema && - this.additionalProperties == other.additionalProperties + id() + _xactId() + functionData().validate() + logId() + name() + orgId() + projectId() + slug() + created() + description() + functionSchema().ifPresent { it.validate() } + functionType() + metadata().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - _xactId, - projectId, - logId, - orgId, - name, - slug, - description, - created, - promptData, - tags, - metadata, - functionType, - functionData, - origin, - functionSchema, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Function{id=$id, _xactId=$_xactId, projectId=$projectId, logId=$logId, orgId=$orgId, name=$name, slug=$slug, description=$description, created=$created, promptData=$promptData, tags=$tags, metadata=$metadata, functionType=$functionType, functionData=$functionData, origin=$origin, functionSchema=$functionSchema, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .functionData() + * .logId() + * .name() + * .orgId() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var id: JsonField = JsonMissing.of() - private var _xactId: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var logId: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var slug: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() + /** A builder for [Function]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var functionData: JsonField? = null + private var logId: JsonField? = null + private var name: JsonField? = null + private var orgId: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null private var created: JsonField = JsonMissing.of() - private var promptData: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var functionSchema: JsonField = JsonMissing.of() private var functionType: JsonField = JsonMissing.of() - private var functionData: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() private var origin: JsonField = JsonMissing.of() - private var functionSchema: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.id = function.id - this._xactId = function._xactId - this.projectId = function.projectId - this.logId = function.logId - this.orgId = function.orgId - this.name = function.name - this.slug = function.slug - this.description = function.description - this.created = function.created - this.promptData = function.promptData - this.tags = function.tags - this.metadata = function.metadata - this.functionType = function.functionType - this.functionData = function.functionData - this.origin = function.origin - this.functionSchema = function.functionSchema - additionalProperties(function.additionalProperties) + id = function.id + _xactId = function._xactId + functionData = function.functionData + logId = function.logId + name = function.name + orgId = function.orgId + projectId = function.projectId + slug = function.slug + created = function.created + description = function.description + functionSchema = function.functionSchema + functionType = function.functionType + metadata = function.metadata + origin = function.origin + promptData = function.promptData + tags = function.tags.map { it.toMutableList() } + additionalProperties = function.additionalProperties.toMutableMap() } /** Unique identifier for the prompt */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the prompt */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } /** * The transaction id of an event is unique to the network operation that processed the @@ -299,160 +438,284 @@ private constructor( fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) /** - * The transaction id of an event is unique to the network operation that processed the - * event insertion. Transaction ids are monotonically increasing over time and can be used - * to retrieve a versioned snapshot of the prompt (see the `version` parameter) + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("_xact_id") - @ExcludeMissing fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } - /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + fun functionData(functionData: FunctionData) = functionData(JsonField.of(functionData)) - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { + this.functionData = functionData + } + + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = functionData(FunctionData.ofPrompt(prompt)) + + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = functionData(FunctionData.ofCode(code)) + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = functionData(FunctionData.ofGlobal(global)) /** A literal 'p' which identifies the object as a project prompt */ fun logId(logId: LogId) = logId(JsonField.of(logId)) - /** A literal 'p' which identifies the object as a project prompt */ - @JsonProperty("log_id") - @ExcludeMissing + /** + * Sets [Builder.logId] to an arbitrary JSON value. + * + * You should usually call [Builder.logId] with a well-typed [LogId] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun logId(logId: JsonField) = apply { this.logId = logId } + /** Name of the prompt */ + 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 } + /** Unique identifier for the organization */ fun orgId(orgId: String) = orgId(JsonField.of(orgId)) - /** Unique identifier for the organization */ - @JsonProperty("org_id") - @ExcludeMissing + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - /** Name of the prompt */ - fun name(name: String) = name(JsonField.of(name)) + /** Unique identifier for the project that the prompt belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Name of the prompt */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ fun slug(slug: String) = slug(JsonField.of(slug)) - /** Unique identifier for the prompt */ - @JsonProperty("slug") - @ExcludeMissing + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun slug(slug: JsonField) = apply { this.slug = slug } - /** Textual description of the prompt */ - fun description(description: String) = description(JsonField.of(description)) - - /** Textual description of the prompt */ - @JsonProperty("description") - @ExcludeMissing - fun description(description: JsonField) = apply { this.description = description } - /** Date of prompt creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) - /** Date of prompt creation */ - @JsonProperty("created") - @ExcludeMissing + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } - /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = promptData(JsonField.of(promptData)) + /** Textual description of the prompt */ + fun description(description: String?) = description(JsonField.ofNullable(description)) - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - @ExcludeMissing - fun promptData(promptData: JsonField) = apply { this.promptData = promptData } + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) - /** A list of tags for the prompt */ - fun tags(tags: List) = tags(JsonField.of(tags)) + /** + * 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 } - /** A list of tags for the prompt */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } + /** JSON schema for the function's parameters and return type */ + fun functionSchema(functionSchema: FunctionSchema?) = + functionSchema(JsonField.ofNullable(functionSchema)) - /** User-controlled metadata about the prompt */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + /** Alias for calling [Builder.functionSchema] with `functionSchema.orElse(null)`. */ + fun functionSchema(functionSchema: Optional) = + functionSchema(functionSchema.getOrNull()) - /** User-controlled metadata about the prompt */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + /** + * Sets [Builder.functionSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.functionSchema] with a well-typed [FunctionSchema] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionSchema(functionSchema: JsonField) = apply { + this.functionSchema = functionSchema + } - fun functionType(functionType: FunctionType) = functionType(JsonField.of(functionType)) + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) - @JsonProperty("function_type") - @ExcludeMissing + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun functionType(functionType: JsonField) = apply { this.functionType = functionType } - fun functionData(functionData: FunctionData) = functionData(JsonField.of(functionData)) + /** User-controlled metadata about the prompt */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) - @JsonProperty("function_data") - @ExcludeMissing - fun functionData(functionData: JsonField) = apply { - this.functionData = functionData - } + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - fun origin(origin: Origin) = origin(JsonField.of(origin)) + fun origin(origin: Origin?) = origin(JsonField.ofNullable(origin)) - @JsonProperty("origin") - @ExcludeMissing + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun origin(origin: JsonField) = apply { this.origin = origin } - /** JSON schema for the function's parameters and return type */ - fun functionSchema(functionSchema: FunctionSchema) = - functionSchema(JsonField.of(functionSchema)) + /** The prompt, model, and its parameters */ + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) - /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") - @ExcludeMissing - fun functionSchema(functionSchema: JsonField) = apply { - this.functionSchema = functionSchema + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { this.promptData = promptData } + + /** A list of tags for the prompt */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .functionData() + * .logId() + * .name() + * .orgId() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( - id, - _xactId, - projectId, - logId, - orgId, - name, - slug, - description, + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("functionData", functionData), + checkRequired("logId", logId), + checkRequired("name", name), + checkRequired("orgId", orgId), + checkRequired("projectId", projectId), + checkRequired("slug", slug), created, - promptData, - tags.map { it.toUnmodifiable() }, - metadata, + description, + functionSchema, functionType, - functionData, + metadata, origin, - functionSchema, - additionalProperties.toUnmodifiable(), + promptData, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } @@ -466,8 +729,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun prompt(): Optional = Optional.ofNullable(prompt) fun code(): Optional = Optional.ofNullable(code) @@ -497,16 +758,29 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): FunctionData = apply { - if (!validated) { - if (prompt == null && code == null && global == null) { - throw BraintrustInvalidDataException("Unknown FunctionData: $_json") - } - prompt?.validate() - code?.validate() - global?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitPrompt(prompt: Prompt) { + prompt.validate() + } + + override fun visitCode(code: Code) { + code.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -514,29 +788,19 @@ private constructor( return true } - return other is FunctionData && - this.prompt == other.prompt && - this.code == other.code && - this.global == other.global + return /* spotless:off */ other is FunctionData && prompt == other.prompt && code == other.code && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - prompt, - code, - global, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(prompt, code, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { prompt != null -> "FunctionData{prompt=$prompt}" code != null -> "FunctionData{code=$code}" global != null -> "FunctionData{global=$global}" _json != null -> "FunctionData{_unknown=$_json}" else -> throw IllegalStateException("Invalid FunctionData") } - } companion object { @@ -547,6 +811,10 @@ private constructor( @JvmStatic fun ofGlobal(global: Global) = FunctionData(global = global) } + /** + * An interface that defines how to map each variant of [FunctionData] to a value of type + * [T]. + */ interface Visitor { fun visitPrompt(prompt: Prompt): T @@ -555,15 +823,26 @@ private constructor( fun visitGlobal(global: Global): T + /** + * Maps an unknown variant of [FunctionData] to a value of type [T]. + * + * An instance of [FunctionData] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown FunctionData: $json") } } - class Deserializer : BaseDeserializer(FunctionData::class) { + internal class Deserializer : BaseDeserializer(FunctionData::class) { override fun ObjectCodec.deserialize(node: JsonNode): FunctionData { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return FunctionData(prompt = it, _json = json) @@ -581,12 +860,12 @@ private constructor( } } - class Serializer : BaseSerializer(FunctionData::class) { + internal class Serializer : BaseSerializer(FunctionData::class) { override fun serialize( value: FunctionData, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.prompt != null -> generator.writeObject(value.prompt) @@ -598,85 +877,91 @@ private constructor( } } - @JsonDeserialize(builder = Prompt.Builder::class) @NoAutoDetect class Prompt + @JsonCreator private constructor( - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Prompt = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Prompt = apply { + if (validated) { + return@apply } - return other is Prompt && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode + type() + validated = true } - override fun toString() = - "Prompt{type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Prompt]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Prompt]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(prompt: Prompt) = apply { - this.type = prompt.type - additionalProperties(prompt.additionalProperties) + type = prompt.type + additionalProperties = prompt.additionalProperties.toMutableMap() } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -684,160 +969,268 @@ private constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Prompt = Prompt(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - return other is Type && this.value == other.value + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [Prompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Prompt = + Prompt(checkRequired("type", type), additionalProperties.toImmutable()) + } - override fun toString() = value.toString() + class Type @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 PROMPT = Type(JsonField.of("prompt")) + @JvmField val PROMPT = of("prompt") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - PROMPT, + PROMPT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { PROMPT, + /** + * An enum member indicating that [Type] 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) { PROMPT -> Value.PROMPT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { PROMPT -> Known.PROMPT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Prompt && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Prompt{type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Code.Builder::class) @NoAutoDetect class Code + @JsonCreator private constructor( - private val type: JsonField, - private val data: JsonField, - private val additionalProperties: Map, + @JsonProperty("data") + @ExcludeMissing + private val data: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 data(): Data = data.getRequired("data") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun data(): Data = data.getRequired("data") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data - @JsonProperty("data") @ExcludeMissing fun _data() = data + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Code = apply { - if (!validated) { - type() - data() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Code = apply { + if (validated) { + return@apply } - return other is Code && - this.type == other.type && - this.data == other.data && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - data, - additionalProperties, - ) - } - return hashCode + data().validate() + type() + validated = true } - override fun toString() = - "Code{type=$type, data=$data, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Code]. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Code]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var data: JsonField = JsonMissing.of() + private var data: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(code: Code) = apply { - this.type = code.type - this.data = code.data - additionalProperties(code.additionalProperties) + data = code.data + type = code.type + additionalProperties = code.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun data(data: Data) = data(JsonField.of(data)) - @JsonProperty("data") - @ExcludeMissing + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun data(data: JsonField) = apply { this.data = data } + /** Alias for calling [data] with `Data.ofBundle(bundle)`. */ + fun data(bundle: Data.Bundle) = data(Data.ofBundle(bundle)) + + /** Alias for calling [data] with `Data.ofInline(inline)`. */ + fun data(inline: Data.Inline) = data(Data.ofInline(inline)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -845,11 +1238,32 @@ private constructor( 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 [Code]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Code = Code( - type, - data, - additionalProperties.toUnmodifiable(), + checkRequired("data", data), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } @@ -862,8 +1276,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun bundle(): Optional = Optional.ofNullable(bundle) fun inline(): Optional = Optional.ofNullable(inline) @@ -886,14 +1298,25 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): Data = apply { - if (!validated) { - if (bundle == null && inline == null) { - throw BraintrustInvalidDataException("Unknown Data: $_json") - } - inline?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitBundle(bundle: Bundle) { + bundle.validate() + } + + override fun visitInline(inline: Inline) { + inline.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -901,23 +1324,18 @@ private constructor( return true } - return other is Data && - this.bundle == other.bundle && - this.inline == other.inline + return /* spotless:off */ other is Data && bundle == other.bundle && inline == other.inline /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(bundle, inline) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(bundle, inline) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { bundle != null -> "Data{bundle=$bundle}" inline != null -> "Data{inline=$inline}" _json != null -> "Data{_unknown=$_json}" else -> throw IllegalStateException("Invalid Data") } - } companion object { @@ -926,24 +1344,40 @@ private constructor( @JvmStatic fun ofInline(inline: Inline) = Data(inline = inline) } + /** + * An interface that defines how to map each variant of [Data] to a value of type + * [T]. + */ interface Visitor { fun visitBundle(bundle: Bundle): T fun visitInline(inline: Inline): T + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Data: $json") } } - class Deserializer : BaseDeserializer(Data::class) { + internal class Deserializer : BaseDeserializer(Data::class) { override fun ObjectCodec.deserialize(node: JsonNode): Data { val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return Data(bundle = it, _json = json) - } + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(bundle = it, _json = json) + } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Data(inline = it, _json = json) @@ -953,12 +1387,12 @@ private constructor( } } - class Serializer : BaseSerializer(Data::class) { + internal class Serializer : BaseSerializer(Data::class) { override fun serialize( value: Data, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.bundle != null -> generator.writeObject(value.bundle) @@ -969,481 +1403,748 @@ private constructor( } } - @JsonDeserialize(builder = Bundle.Builder::class) @NoAutoDetect class Bundle + @JsonCreator private constructor( - private val runtimeContext: JsonField, - private val location: JsonField, - private val bundleId: JsonField, - private val preview: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("bundle_id") + @ExcludeMissing + private val bundleId: JsonField = JsonMissing.of(), + @JsonProperty("location") + @ExcludeMissing + private val location: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = + JsonMissing.of(), + @JsonProperty("preview") + @ExcludeMissing + private val preview: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * @throws BraintrustInvalidDataException 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 bundleId(): String = bundleId.getRequired("bundle_id") - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 location(): CodeBundle.Location = location.getRequired("location") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): CodeBundle.RuntimeContext = runtimeContext.getRequired("runtime_context") - fun location(): CodeBundle.Location = location.getRequired("location") - - fun bundleId(): String = bundleId.getRequired("bundle_id") - - /** A preview of the code */ + /** + * A preview of the code + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun preview(): Optional = Optional.ofNullable(preview.getNullable("preview")) + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun toCodeBundle(): CodeBundle = - CodeBundle.builder() - .runtimeContext(runtimeContext) - .location(location) - .bundleId(bundleId) - .preview(preview) - .build() - + /** + * Returns the raw JSON value of [bundleId]. + * + * Unlike [bundleId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("bundle_id") + @ExcludeMissing + fun _bundleId(): JsonField = bundleId + + /** + * Returns the raw JSON value of [location]. + * + * Unlike [location], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("location") + @ExcludeMissing + fun _location(): JsonField = location + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext - - @JsonProperty("location") @ExcludeMissing fun _location() = location - - @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId() = bundleId - - /** A preview of the code */ - @JsonProperty("preview") @ExcludeMissing fun _preview() = preview + fun _runtimeContext(): JsonField = runtimeContext + + /** + * Returns the raw JSON value of [preview]. + * + * Unlike [preview], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("preview") + @ExcludeMissing + fun _preview(): JsonField = preview - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Bundle = apply { - if (!validated) { - runtimeContext().validate() - location() - bundleId() - preview() - type() - validated = true - } - } + fun toCodeBundle(): CodeBundle = + CodeBundle.builder() + .bundleId(bundleId) + .location(location) + .runtimeContext(runtimeContext) + .preview(preview) + .build() - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Bundle = apply { + if (validated) { + return@apply } - return other is Bundle && - this.runtimeContext == other.runtimeContext && - this.location == other.location && - this.bundleId == other.bundleId && - this.preview == other.preview && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtimeContext, - location, - bundleId, - preview, - type, - additionalProperties, - ) - } - return hashCode + bundleId() + location().validate() + runtimeContext().validate() + preview() + type() + validated = true } - override fun toString() = - "Bundle{runtimeContext=$runtimeContext, location=$location, bundleId=$bundleId, preview=$preview, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Bundle]. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Bundle]. */ + class Builder internal constructor() { - private var runtimeContext: JsonField = - JsonMissing.of() - private var location: JsonField = JsonMissing.of() - private var bundleId: JsonField = JsonMissing.of() + private var bundleId: JsonField? = null + private var location: JsonField? = null + private var runtimeContext: JsonField? = null private var preview: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(bundle: Bundle) = apply { - this.runtimeContext = bundle.runtimeContext - this.location = bundle.location - this.bundleId = bundle.bundleId - this.preview = bundle.preview - this.type = bundle.type - additionalProperties(bundle.additionalProperties) + bundleId = bundle.bundleId + location = bundle.location + runtimeContext = bundle.runtimeContext + preview = bundle.preview + type = bundle.type + additionalProperties = bundle.additionalProperties.toMutableMap() } - fun runtimeContext(runtimeContext: CodeBundle.RuntimeContext) = - runtimeContext(JsonField.of(runtimeContext)) + fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - @JsonProperty("runtime_context") - @ExcludeMissing - fun runtimeContext(runtimeContext: JsonField) = - apply { - this.runtimeContext = runtimeContext - } + /** + * Sets [Builder.bundleId] to an arbitrary JSON value. + * + * You should usually call [Builder.bundleId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun bundleId(bundleId: JsonField) = apply { + this.bundleId = bundleId + } fun location(location: CodeBundle.Location) = location(JsonField.of(location)) - @JsonProperty("location") - @ExcludeMissing + /** + * Sets [Builder.location] to an arbitrary JSON value. + * + * You should usually call [Builder.location] with a well-typed + * [CodeBundle.Location] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ fun location(location: JsonField) = apply { this.location = location } - fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofExperiment(experiment)`. + */ + fun location(experiment: CodeBundle.Location.Experiment) = + location(CodeBundle.Location.ofExperiment(experiment)) - @JsonProperty("bundle_id") - @ExcludeMissing - fun bundleId(bundleId: JsonField) = apply { - this.bundleId = bundleId - } + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofFunction(function)`. + */ + fun location(function: CodeBundle.Location.Function) = + location(CodeBundle.Location.ofFunction(function)) - /** A preview of the code */ - fun preview(preview: String) = preview(JsonField.of(preview)) + fun runtimeContext(runtimeContext: CodeBundle.RuntimeContext) = + runtimeContext(JsonField.of(runtimeContext)) + + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [CodeBundle.RuntimeContext] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun runtimeContext(runtimeContext: JsonField) = + apply { + this.runtimeContext = runtimeContext + } /** A preview of the code */ - @JsonProperty("preview") - @ExcludeMissing + fun preview(preview: String?) = preview(JsonField.ofNullable(preview)) + + /** Alias for calling [Builder.preview] with `preview.orElse(null)`. */ + fun preview(preview: Optional) = preview(preview.getOrNull()) + + /** + * Sets [Builder.preview] to an arbitrary JSON value. + * + * You should usually call [Builder.preview] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun preview(preview: JsonField) = apply { this.preview = preview } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Bundle]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Bundle = Bundle( - runtimeContext, - location, - bundleId, + checkRequired("bundleId", bundleId), + checkRequired("location", location), + checkRequired("runtimeContext", runtimeContext), preview, - type, - additionalProperties.toUnmodifiable(), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } class Type @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val BUNDLE = Type(JsonField.of("bundle")) + @JvmField val BUNDLE = of("bundle") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - BUNDLE, + BUNDLE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { BUNDLE, + /** + * An enum member indicating that [Type] 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) { BUNDLE -> Value.BUNDLE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { BUNDLE -> Known.BUNDLE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Bundle && bundleId == other.bundleId && location == other.location && runtimeContext == other.runtimeContext && preview == other.preview && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(bundleId, location, runtimeContext, preview, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Bundle{bundleId=$bundleId, location=$location, runtimeContext=$runtimeContext, preview=$preview, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Inline.Builder::class) @NoAutoDetect class Inline + @JsonCreator private constructor( - private val type: JsonField, - private val runtimeContext: JsonField, - private val code: JsonField, - private val additionalProperties: Map, + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") - fun code(): String = code.getRequired("code") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext + fun _runtimeContext(): JsonField = runtimeContext - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Inline = apply { - if (!validated) { - type() - runtimeContext().validate() - code() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Inline = apply { + if (validated) { + return@apply } - return other is Inline && - this.type == other.type && - this.runtimeContext == other.runtimeContext && - this.code == other.code && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - runtimeContext, - code, - additionalProperties, - ) - } - return hashCode + code() + runtimeContext().validate() + type() + validated = true } - override fun toString() = - "Inline{type=$type, runtimeContext=$runtimeContext, code=$code, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Inline]. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Inline]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var runtimeContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() + private var code: JsonField? = null + private var runtimeContext: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inline: Inline) = apply { - this.type = inline.type - this.runtimeContext = inline.runtimeContext - this.code = inline.code - additionalProperties(inline.additionalProperties) + code = inline.code + runtimeContext = inline.runtimeContext + type = inline.type + additionalProperties = inline.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) + fun code(code: String) = code(JsonField.of(code)) - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } fun runtimeContext(runtimeContext: RuntimeContext) = runtimeContext(JsonField.of(runtimeContext)) - @JsonProperty("runtime_context") - @ExcludeMissing + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [RuntimeContext] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun runtimeContext(runtimeContext: JsonField) = apply { this.runtimeContext = runtimeContext } - fun code(code: String) = code(JsonField.of(code)) + fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Inline]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Inline = Inline( - type, - runtimeContext, - code, - additionalProperties.toUnmodifiable(), + checkRequired("code", code), + checkRequired("runtimeContext", runtimeContext), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = RuntimeContext.Builder::class) @NoAutoDetect class RuntimeContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime - - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("version") + @ExcludeMissing + fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RuntimeContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RuntimeContext = apply { + if (validated) { + return@apply } - return other is RuntimeContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [RuntimeContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RuntimeContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(runtimeContext: RuntimeContext) = apply { - this.runtime = runtimeContext.runtime - this.version = runtimeContext.version - additionalProperties(runtimeContext.additionalProperties) + runtime = runtimeContext.runtime + version = runtimeContext.version + additionalProperties = + runtimeContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } @@ -1451,67 +2152,106 @@ private constructor( fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RuntimeContext]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RuntimeContext = RuntimeContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } class Runtime @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -1519,6 +2259,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value + * is a not a known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -1529,215 +2278,403 @@ private constructor( ) } - fun asString(): String = _value().asStringOrThrow() - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is RuntimeContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + class Type + @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 INLINE = Type(JsonField.of("inline")) + @JvmField val INLINE = of("inline") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - INLINE, + INLINE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { INLINE, + /** + * An enum member indicating that [Type] 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) { INLINE -> Value.INLINE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { INLINE -> Known.INLINE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - return other is Type && this.value == other.value - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun hashCode() = value.hashCode() + return /* spotless:off */ other is Inline && code == other.code && runtimeContext == other.runtimeContext && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - override fun toString() = value.toString() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, runtimeContext, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Inline{code=$code, runtimeContext=$runtimeContext, type=$type, additionalProperties=$additionalProperties}" + } + } + + class Type @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 CODE = Type(JsonField.of("code")) + @JvmField val CODE = of("code") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - CODE, + CODE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { CODE, + /** + * An enum member indicating that [Type] 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) { CODE -> Value.CODE 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { CODE -> Known.CODE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Code && data == other.data && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Code{data=$data, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1745,186 +2682,287 @@ private constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class LogId - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is LogId && this.value == other.value + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" } + } - override fun hashCode() = value.hashCode() + /** A literal 'p' which identifies the object as a project prompt */ + class LogId @JsonCreator private constructor(private val value: JsonField) : Enum { - override fun toString() = value.toString() + /** + * 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 P = LogId(JsonField.of("p")) + @JvmField val P = of("p") @JvmStatic fun of(value: String) = LogId(JsonField.of(value)) } + /** An enum containing [LogId]'s known values. */ enum class Known { - P, + P } + /** + * An enum containing [LogId]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [LogId] 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 { P, + /** An enum member indicating that [LogId] 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) { P -> Value.P 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { P -> Known.P else -> throw BraintrustInvalidDataException("Unknown LogId: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is LogId && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } /** JSON schema for the function's parameters and return type */ - @JsonDeserialize(builder = FunctionSchema.Builder::class) @NoAutoDetect class FunctionSchema + @JsonCreator private constructor( - private val parameters: JsonValue, - private val returns: JsonValue, - private val additionalProperties: Map, + @JsonProperty("parameters") + @ExcludeMissing + private val parameters: JsonValue = JsonMissing.of(), + @JsonProperty("returns") @ExcludeMissing private val returns: JsonValue = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + @JsonProperty("parameters") @ExcludeMissing fun _parameters(): JsonValue = parameters - fun parameters(): JsonValue = parameters - - fun returns(): JsonValue = returns - - @JsonProperty("parameters") @ExcludeMissing fun _parameters() = parameters - - @JsonProperty("returns") @ExcludeMissing fun _returns() = returns + @JsonProperty("returns") @ExcludeMissing fun _returns(): JsonValue = returns @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FunctionSchema = apply { - if (!validated) { - parameters() - returns() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionSchema = apply { + if (validated) { + return@apply } - return other is FunctionSchema && - this.parameters == other.parameters && - this.returns == other.returns && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - parameters, - returns, - additionalProperties, - ) - } - return hashCode + validated = true } - override fun toString() = - "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [FunctionSchema]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionSchema]. */ + class Builder internal constructor() { private var parameters: JsonValue = JsonMissing.of() private var returns: JsonValue = JsonMissing.of() @@ -1932,75 +2970,88 @@ private constructor( @JvmSynthetic internal fun from(functionSchema: FunctionSchema) = apply { - this.parameters = functionSchema.parameters - this.returns = functionSchema.returns - additionalProperties(functionSchema.additionalProperties) + parameters = functionSchema.parameters + returns = functionSchema.returns + additionalProperties = functionSchema.additionalProperties.toMutableMap() } - @JsonProperty("parameters") - @ExcludeMissing fun parameters(parameters: JsonValue) = apply { this.parameters = parameters } - @JsonProperty("returns") - @ExcludeMissing fun returns(returns: JsonValue) = apply { this.returns = returns } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionSchema = - FunctionSchema( - parameters, - returns, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [FunctionSchema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FunctionSchema = + FunctionSchema(parameters, returns, additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is FunctionType && this.value == other.value + return /* spotless:off */ other is FunctionSchema && parameters == other.parameters && returns == other.returns && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(parameters, returns, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + } + + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -2008,14 +3059,33 @@ private constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -2025,6 +3095,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -2034,347 +3113,356 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } /** User-controlled metadata about the prompt */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Origin.Builder::class) @NoAutoDetect class Origin + @JsonCreator private constructor( - private val objectType: JsonField, - private val objectId: JsonField, - private val internal_: JsonField, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("internal") + @ExcludeMissing + private val internal_: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The object type that the ACL applies to */ - fun objectType(): ObjectType = objectType.getRequired("object_type") - - /** Id of the object the function is originating from */ + /** + * Id of the object the function is originating from + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + /** * The function exists for internal purposes and should not be displayed in the list of * functions. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ fun internal_(): Optional = Optional.ofNullable(internal_.getNullable("internal")) - /** The object type that the ACL applies to */ - @JsonProperty("object_type") @ExcludeMissing fun _objectType() = objectType + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId - /** Id of the object the function is originating from */ - @JsonProperty("object_id") @ExcludeMissing fun _objectId() = objectId + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType /** - * The function exists for internal purposes and should not be displayed in the list of - * functions. + * Returns the raw JSON value of [internal_]. + * + * Unlike [internal_], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("internal") @ExcludeMissing fun _internal_() = internal_ + @JsonProperty("internal") @ExcludeMissing fun _internal_(): JsonField = internal_ @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Origin = apply { - if (!validated) { - objectType() - objectId() - internal_() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Origin = apply { + if (validated) { + return@apply } - return other is Origin && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.internal_ == other.internal_ && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - internal_, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + internal_() + validated = true } - override fun toString() = - "Origin{objectType=$objectType, objectId=$objectId, internal_=$internal_, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Origin]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Origin]. */ + class Builder internal constructor() { - private var objectType: JsonField = JsonMissing.of() - private var objectId: JsonField = JsonMissing.of() + private var objectId: JsonField? = null + private var objectType: JsonField? = null private var internal_: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(origin: Origin) = apply { - this.objectType = origin.objectType - this.objectId = origin.objectId - this.internal_ = origin.internal_ - additionalProperties(origin.additionalProperties) - } - - /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") - @ExcludeMissing - fun objectType(objectType: JsonField) = apply { - this.objectType = objectType + objectId = origin.objectId + objectType = origin.objectType + internal_ = origin.internal_ + additionalProperties = origin.additionalProperties.toMutableMap() } /** Id of the object the function is originating from */ fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - /** Id of the object the function is originating from */ - @JsonProperty("object_id") - @ExcludeMissing + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + /** The object type that the ACL applies to */ + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + /** - * The function exists for internal purposes and should not be displayed in the list of - * functions. + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun internal_(internal_: Boolean) = internal_(JsonField.of(internal_)) + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * The function exists for internal purposes and should not be displayed in the list of * functions. */ - @JsonProperty("internal") - @ExcludeMissing + fun internal_(internal_: Boolean?) = internal_(JsonField.ofNullable(internal_)) + + /** + * Alias for [Builder.internal_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun internal_(internal_: Boolean) = internal_(internal_ as Boolean?) + + /** Alias for calling [Builder.internal_] with `internal_.orElse(null)`. */ + fun internal_(internal_: Optional) = internal_(internal_.getOrNull()) + + /** + * Sets [Builder.internal_] to an arbitrary JSON value. + * + * You should usually call [Builder.internal_] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun internal_(internal_: JsonField) = apply { this.internal_ = internal_ } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Origin]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Origin = Origin( - objectType, - objectId, + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), internal_, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + return /* spotless:off */ other is Origin && objectId == other.objectId && objectType == other.objectType && internal_ == other.internal_ && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, internal_, additionalProperties) } + /* spotless:on */ - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + override fun hashCode(): Int = hashCode - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } + override fun toString() = + "Origin{objectId=$objectId, objectType=$objectType, internal_=$internal_, additionalProperties=$additionalProperties}" + } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + return /* spotless:off */ other is Function && id == other.id && _xactId == other._xactId && functionData == other.functionData && logId == other.logId && name == other.name && orgId == other.orgId && projectId == other.projectId && slug == other.slug && created == other.created && description == other.description && functionSchema == other.functionSchema && functionType == other.functionType && metadata == other.metadata && origin == other.origin && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, functionData, logId, name, orgId, projectId, slug, created, description, functionSchema, functionType, metadata, origin, promptData, tags, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "Function{id=$id, _xactId=$_xactId, functionData=$functionData, logId=$logId, name=$name, orgId=$orgId, projectId=$projectId, slug=$slug, created=$created, description=$description, functionSchema=$functionSchema, functionType=$functionType, metadata=$metadata, origin=$origin, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionCreateParams.kt index 47041902..f902f77a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionCreateParams.kt @@ -10,8 +10,14 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.braintrustdata.api.models.CodeBundle.* import com.fasterxml.jackson.annotation.JsonAnyGetter @@ -27,468 +33,1014 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new function. If there is an existing function in the project with the same slug as the + * one specified in the request, will return the existing function unmodified + */ class FunctionCreateParams -constructor( - private val functionData: FunctionData, - private val name: String, - private val projectId: String, - private val slug: String, - private val description: String?, - private val functionSchema: FunctionSchema?, - private val functionType: FunctionType?, - private val origin: Origin?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun functionData(): FunctionData = functionData - - fun name(): String = name - - fun projectId(): String = projectId - - fun slug(): String = slug - - fun description(): Optional = Optional.ofNullable(description) - - fun functionSchema(): Optional = Optional.ofNullable(functionSchema) - - fun functionType(): Optional = Optional.ofNullable(functionType) - - fun origin(): Optional = Optional.ofNullable(origin) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): FunctionCreateBody { - return FunctionCreateBody( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws BraintrustInvalidDataException 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 functionData(): FunctionData = body.functionData() + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = body.slug() + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * JSON schema for the function's parameters and return type + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionSchema(): Optional = body.functionSchema() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionType(): Optional = body.functionType() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = body.origin() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionData(): JsonField = body._functionData() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _slug(): JsonField = body._slug() + + /** + * 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 [functionSchema]. + * + * Unlike [functionSchema], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionSchema(): JsonField = body._functionSchema() + + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionType(): JsonField = body._functionType() + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _origin(): JsonField = body._origin() + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = FunctionCreateBody.Builder::class) @NoAutoDetect - class FunctionCreateBody - internal constructor( - private val functionData: FunctionData?, - private val name: String?, - private val projectId: String?, - private val slug: String?, - private val description: String?, - private val functionSchema: FunctionSchema?, - private val functionType: FunctionType?, - private val origin: Origin?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("function_data") + @ExcludeMissing + private val functionData: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_schema") + @ExcludeMissing + private val functionSchema: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 functionData(): FunctionData = functionData.getRequired("function_data") - @JsonProperty("function_data") fun functionData(): FunctionData? = functionData + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") - /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(): String? = slug + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description + /** + * JSON schema for the function's parameters and return type + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionSchema(): Optional = + Optional.ofNullable(functionSchema.getNullable("function_schema")) - /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") fun functionSchema(): FunctionSchema? = functionSchema + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionType(): Optional = + Optional.ofNullable(functionType.getNullable("function_type")) - @JsonProperty("function_type") fun functionType(): FunctionType? = functionType + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) - @JsonProperty("origin") fun origin(): Origin? = origin + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * Returns the raw JSON value of [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_data") + @ExcludeMissing + fun _functionData(): JsonField = functionData + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * 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 [functionSchema]. + * + * Unlike [functionSchema], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_schema") + @ExcludeMissing + fun _functionSchema(): JsonField = functionSchema + + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is FunctionCreateBody && - this.functionData == other.functionData && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionSchema == other.functionSchema && - this.functionType == other.functionType && - this.origin == other.origin && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalProperties, - ) - } - return hashCode + functionData().validate() + name() + projectId() + slug() + description() + functionSchema().ifPresent { it.validate() } + functionType() + origin().ifPresent { it.validate() } + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun toString() = - "FunctionCreateBody{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var functionData: FunctionData? = null - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionSchema: FunctionSchema? = null - private var functionType: FunctionType? = null - private var origin: Origin? = null - private var promptData: PromptData? = null - private var tags: List? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var functionData: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var functionSchema: JsonField = JsonMissing.of() + private var functionType: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(functionCreateBody: FunctionCreateBody) = apply { - this.functionData = functionCreateBody.functionData - this.name = functionCreateBody.name - this.projectId = functionCreateBody.projectId - this.slug = functionCreateBody.slug - this.description = functionCreateBody.description - this.functionSchema = functionCreateBody.functionSchema - this.functionType = functionCreateBody.functionType - this.origin = functionCreateBody.origin - this.promptData = functionCreateBody.promptData - this.tags = functionCreateBody.tags - additionalProperties(functionCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + functionData = body.functionData + name = body.name + projectId = body.projectId + slug = body.slug + description = body.description + functionSchema = body.functionSchema + functionType = body.functionType + origin = body.origin + promptData = body.promptData + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } - @JsonProperty("function_data") - fun functionData(functionData: FunctionData) = apply { + fun functionData(functionData: FunctionData) = functionData(JsonField.of(functionData)) + + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { this.functionData = functionData } + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = + functionData(FunctionData.ofPrompt(prompt)) + + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = functionData(FunctionData.ofCode(code)) + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = + functionData(FunctionData.ofGlobal(global)) + /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = slug(JsonField.of(slug)) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") - fun functionSchema(functionSchema: FunctionSchema) = apply { + fun functionSchema(functionSchema: FunctionSchema?) = + functionSchema(JsonField.ofNullable(functionSchema)) + + /** Alias for calling [Builder.functionSchema] with `functionSchema.orElse(null)`. */ + fun functionSchema(functionSchema: Optional) = + functionSchema(functionSchema.getOrNull()) + + /** + * Sets [Builder.functionSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.functionSchema] with a well-typed [FunctionSchema] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun functionSchema(functionSchema: JsonField) = apply { this.functionSchema = functionSchema } - @JsonProperty("function_type") - fun functionType(functionType: FunctionType) = apply { + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { this.functionType = functionType } - @JsonProperty("origin") fun origin(origin: Origin) = apply { this.origin = origin } + fun origin(origin: Origin?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionCreateBody = - FunctionCreateBody( - checkNotNull(functionData) { "`functionData` is required but was not set" }, - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, + 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 + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("functionData", functionData), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("slug", slug), description, functionSchema, functionType, origin, promptData, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && functionData == other.functionData && name == other.name && projectId == other.projectId && slug == other.slug && description == other.description && functionSchema == other.functionSchema && functionType == other.functionType && origin == other.origin && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is FunctionCreateParams && - this.functionData == other.functionData && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionSchema == other.functionSchema && - this.functionType == other.functionType && - this.origin == other.origin && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(functionData, name, projectId, slug, description, functionSchema, functionType, origin, promptData, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "FunctionCreateParams{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionCreateParams]. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionCreateParams]. */ @NoAutoDetect - class Builder { - - private var functionData: FunctionData? = null - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionSchema: FunctionSchema? = null - private var functionType: FunctionType? = null - private var origin: Origin? = null - private var promptData: PromptData? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(functionCreateParams: FunctionCreateParams) = apply { - this.functionData = functionCreateParams.functionData - this.name = functionCreateParams.name - this.projectId = functionCreateParams.projectId - this.slug = functionCreateParams.slug - this.description = functionCreateParams.description - this.functionSchema = functionCreateParams.functionSchema - this.functionType = functionCreateParams.functionType - this.origin = functionCreateParams.origin - this.promptData = functionCreateParams.promptData - this.tags(functionCreateParams.tags ?: listOf()) - additionalQueryParams(functionCreateParams.additionalQueryParams) - additionalHeaders(functionCreateParams.additionalHeaders) - additionalBodyProperties(functionCreateParams.additionalBodyProperties) + body = functionCreateParams.body.toBuilder() + additionalHeaders = functionCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = functionCreateParams.additionalQueryParams.toBuilder() } - fun functionData(functionData: FunctionData) = apply { this.functionData = functionData } + fun functionData(functionData: FunctionData) = apply { body.functionData(functionData) } - fun functionData(prompt: FunctionData.Prompt) = apply { - this.functionData = FunctionData.ofPrompt(prompt) + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { + body.functionData(functionData) } - fun functionData(code: FunctionData.Code) = apply { - this.functionData = FunctionData.ofCode(code) - } + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = apply { body.functionData(prompt) } - fun functionData(global: FunctionData.Global) = apply { - this.functionData = FunctionData.ofGlobal(global) - } + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = apply { body.functionData(code) } + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = apply { body.functionData(global) } /** Name of the prompt */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Unique identifier for the prompt */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = apply { body.slug(slug) } + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun slug(slug: JsonField) = apply { body.slug(slug) } /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + 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) } /** JSON schema for the function's parameters and return type */ - fun functionSchema(functionSchema: FunctionSchema) = apply { - this.functionSchema = functionSchema + fun functionSchema(functionSchema: FunctionSchema?) = apply { + body.functionSchema(functionSchema) } - fun functionType(functionType: FunctionType) = apply { this.functionType = functionType } + /** Alias for calling [Builder.functionSchema] with `functionSchema.orElse(null)`. */ + fun functionSchema(functionSchema: Optional) = + functionSchema(functionSchema.getOrNull()) - fun origin(origin: Origin) = apply { this.origin = origin } + /** + * Sets [Builder.functionSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.functionSchema] with a well-typed [FunctionSchema] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionSchema(functionSchema: JsonField) = apply { + body.functionSchema(functionSchema) + } - /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun functionType(functionType: FunctionType?) = apply { body.functionType(functionType) } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { + body.functionType(functionType) } + fun origin(origin: Origin?) = apply { body.origin(origin) } + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun origin(origin: JsonField) = apply { body.origin(origin) } + + /** The prompt, model, and its parameters */ + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } + /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun tags(tags: List?) = apply { body.tags(tags) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [FunctionCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionCreateParams = FunctionCreateParams( - checkNotNull(functionData) { "`functionData` is required but was not set" }, - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, - description, - functionSchema, - functionType, - origin, - promptData, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -502,8 +1054,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun prompt(): Optional = Optional.ofNullable(prompt) fun code(): Optional = Optional.ofNullable(code) @@ -533,16 +1083,29 @@ constructor( } } + private var validated: Boolean = false + fun validate(): FunctionData = apply { - if (!validated) { - if (prompt == null && code == null && global == null) { - throw BraintrustInvalidDataException("Unknown FunctionData: $_json") - } - prompt?.validate() - code?.validate() - global?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitPrompt(prompt: Prompt) { + prompt.validate() + } + + override fun visitCode(code: Code) { + code.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -550,29 +1113,19 @@ constructor( return true } - return other is FunctionData && - this.prompt == other.prompt && - this.code == other.code && - this.global == other.global + return /* spotless:off */ other is FunctionData && prompt == other.prompt && code == other.code && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - prompt, - code, - global, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(prompt, code, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { prompt != null -> "FunctionData{prompt=$prompt}" code != null -> "FunctionData{code=$code}" global != null -> "FunctionData{global=$global}" _json != null -> "FunctionData{_unknown=$_json}" else -> throw IllegalStateException("Invalid FunctionData") } - } companion object { @@ -583,6 +1136,10 @@ constructor( @JvmStatic fun ofGlobal(global: Global) = FunctionData(global = global) } + /** + * An interface that defines how to map each variant of [FunctionData] to a value of type + * [T]. + */ interface Visitor { fun visitPrompt(prompt: Prompt): T @@ -591,15 +1148,26 @@ constructor( fun visitGlobal(global: Global): T + /** + * Maps an unknown variant of [FunctionData] to a value of type [T]. + * + * An instance of [FunctionData] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown FunctionData: $json") } } - class Deserializer : BaseDeserializer(FunctionData::class) { + internal class Deserializer : BaseDeserializer(FunctionData::class) { override fun ObjectCodec.deserialize(node: JsonNode): FunctionData { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return FunctionData(prompt = it, _json = json) @@ -617,12 +1185,12 @@ constructor( } } - class Serializer : BaseSerializer(FunctionData::class) { + internal class Serializer : BaseSerializer(FunctionData::class) { override fun serialize( value: FunctionData, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.prompt != null -> generator.writeObject(value.prompt) @@ -634,85 +1202,91 @@ constructor( } } - @JsonDeserialize(builder = Prompt.Builder::class) @NoAutoDetect class Prompt + @JsonCreator private constructor( - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Prompt = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Prompt = apply { + if (validated) { + return@apply } - return other is Prompt && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode + type() + validated = true } - override fun toString() = - "Prompt{type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Prompt]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Prompt]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(prompt: Prompt) = apply { - this.type = prompt.type - additionalProperties(prompt.additionalProperties) + type = prompt.type + additionalProperties = prompt.additionalProperties.toMutableMap() } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -720,160 +1294,268 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Prompt = Prompt(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - return other is Type && this.value == other.value + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [Prompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Prompt = + Prompt(checkRequired("type", type), additionalProperties.toImmutable()) + } - override fun toString() = value.toString() + class Type @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 PROMPT = Type(JsonField.of("prompt")) + @JvmField val PROMPT = of("prompt") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - PROMPT, + PROMPT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { PROMPT, + /** + * An enum member indicating that [Type] 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) { PROMPT -> Value.PROMPT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { PROMPT -> Known.PROMPT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Prompt && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Prompt{type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Code.Builder::class) @NoAutoDetect class Code + @JsonCreator private constructor( - private val type: JsonField, - private val data: JsonField, - private val additionalProperties: Map, + @JsonProperty("data") + @ExcludeMissing + private val data: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 data(): Data = data.getRequired("data") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun data(): Data = data.getRequired("data") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data - @JsonProperty("data") @ExcludeMissing fun _data() = data + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Code = apply { - if (!validated) { - type() - data() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Code = apply { + if (validated) { + return@apply } - return other is Code && - this.type == other.type && - this.data == other.data && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - data, - additionalProperties, - ) - } - return hashCode + data().validate() + type() + validated = true } - override fun toString() = - "Code{type=$type, data=$data, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Code]. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Code]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var data: JsonField = JsonMissing.of() + private var data: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(code: Code) = apply { - this.type = code.type - this.data = code.data - additionalProperties(code.additionalProperties) + data = code.data + type = code.type + additionalProperties = code.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun data(data: Data) = data(JsonField.of(data)) - @JsonProperty("data") - @ExcludeMissing + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun data(data: JsonField) = apply { this.data = data } + /** Alias for calling [data] with `Data.ofBundle(bundle)`. */ + fun data(bundle: Data.Bundle) = data(Data.ofBundle(bundle)) + + /** Alias for calling [data] with `Data.ofInline(inline)`. */ + fun data(inline: Data.Inline) = data(Data.ofInline(inline)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -881,11 +1563,32 @@ constructor( 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 [Code]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Code = Code( - type, - data, - additionalProperties.toUnmodifiable(), + checkRequired("data", data), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } @@ -898,8 +1601,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun bundle(): Optional = Optional.ofNullable(bundle) fun inline(): Optional = Optional.ofNullable(inline) @@ -922,14 +1623,25 @@ constructor( } } + private var validated: Boolean = false + fun validate(): Data = apply { - if (!validated) { - if (bundle == null && inline == null) { - throw BraintrustInvalidDataException("Unknown Data: $_json") - } - inline?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitBundle(bundle: Bundle) { + bundle.validate() + } + + override fun visitInline(inline: Inline) { + inline.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -937,23 +1649,18 @@ constructor( return true } - return other is Data && - this.bundle == other.bundle && - this.inline == other.inline + return /* spotless:off */ other is Data && bundle == other.bundle && inline == other.inline /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(bundle, inline) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(bundle, inline) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { bundle != null -> "Data{bundle=$bundle}" inline != null -> "Data{inline=$inline}" _json != null -> "Data{_unknown=$_json}" else -> throw IllegalStateException("Invalid Data") } - } companion object { @@ -962,24 +1669,40 @@ constructor( @JvmStatic fun ofInline(inline: Inline) = Data(inline = inline) } + /** + * An interface that defines how to map each variant of [Data] to a value of type + * [T]. + */ interface Visitor { fun visitBundle(bundle: Bundle): T fun visitInline(inline: Inline): T + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Data: $json") } } - class Deserializer : BaseDeserializer(Data::class) { + internal class Deserializer : BaseDeserializer(Data::class) { override fun ObjectCodec.deserialize(node: JsonNode): Data { val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return Data(bundle = it, _json = json) - } + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(bundle = it, _json = json) + } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Data(inline = it, _json = json) @@ -989,12 +1712,12 @@ constructor( } } - class Serializer : BaseSerializer(Data::class) { + internal class Serializer : BaseSerializer(Data::class) { override fun serialize( value: Data, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.bundle != null -> generator.writeObject(value.bundle) @@ -1005,478 +1728,748 @@ constructor( } } - @JsonDeserialize(builder = Bundle.Builder::class) @NoAutoDetect class Bundle + @JsonCreator private constructor( - private val runtimeContext: JsonField, - private val location: JsonField, - private val bundleId: JsonField, - private val preview: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("bundle_id") + @ExcludeMissing + private val bundleId: JsonField = JsonMissing.of(), + @JsonProperty("location") + @ExcludeMissing + private val location: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = + JsonMissing.of(), + @JsonProperty("preview") + @ExcludeMissing + private val preview: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 bundleId(): String = bundleId.getRequired("bundle_id") - fun runtimeContext(): RuntimeContext = + /** + * @throws BraintrustInvalidDataException 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 location(): CodeBundle.Location = location.getRequired("location") + + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): CodeBundle.RuntimeContext = runtimeContext.getRequired("runtime_context") - fun location(): Location = location.getRequired("location") - - fun bundleId(): String = bundleId.getRequired("bundle_id") - - /** A preview of the code */ + /** + * A preview of the code + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun preview(): Optional = Optional.ofNullable(preview.getNullable("preview")) + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun toCodeBundle(): CodeBundle = - CodeBundle.builder() - .runtimeContext(runtimeContext) - .location(location) - .bundleId(bundleId) - .preview(preview) - .build() - + /** + * Returns the raw JSON value of [bundleId]. + * + * Unlike [bundleId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("bundle_id") + @ExcludeMissing + fun _bundleId(): JsonField = bundleId + + /** + * Returns the raw JSON value of [location]. + * + * Unlike [location], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("location") + @ExcludeMissing + fun _location(): JsonField = location + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext - - @JsonProperty("location") @ExcludeMissing fun _location() = location - - @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId() = bundleId - - /** A preview of the code */ - @JsonProperty("preview") @ExcludeMissing fun _preview() = preview + fun _runtimeContext(): JsonField = runtimeContext + + /** + * Returns the raw JSON value of [preview]. + * + * Unlike [preview], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("preview") + @ExcludeMissing + fun _preview(): JsonField = preview - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Bundle = apply { - if (!validated) { - runtimeContext().validate() - location() - bundleId() - preview() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun toCodeBundle(): CodeBundle = + CodeBundle.builder() + .bundleId(bundleId) + .location(location) + .runtimeContext(runtimeContext) + .preview(preview) + .build() - return other is Bundle && - this.runtimeContext == other.runtimeContext && - this.location == other.location && - this.bundleId == other.bundleId && - this.preview == other.preview && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtimeContext, - location, - bundleId, - preview, - type, - additionalProperties, - ) + fun validate(): Bundle = apply { + if (validated) { + return@apply } - return hashCode + + bundleId() + location().validate() + runtimeContext().validate() + preview() + type() + validated = true } - override fun toString() = - "Bundle{runtimeContext=$runtimeContext, location=$location, bundleId=$bundleId, preview=$preview, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Bundle]. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Bundle]. */ + class Builder internal constructor() { - private var runtimeContext: JsonField = JsonMissing.of() - private var location: JsonField = JsonMissing.of() - private var bundleId: JsonField = JsonMissing.of() + private var bundleId: JsonField? = null + private var location: JsonField? = null + private var runtimeContext: JsonField? = null private var preview: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(bundle: Bundle) = apply { - this.runtimeContext = bundle.runtimeContext - this.location = bundle.location - this.bundleId = bundle.bundleId - this.preview = bundle.preview - this.type = bundle.type - additionalProperties(bundle.additionalProperties) + bundleId = bundle.bundleId + location = bundle.location + runtimeContext = bundle.runtimeContext + preview = bundle.preview + type = bundle.type + additionalProperties = bundle.additionalProperties.toMutableMap() } - fun runtimeContext(runtimeContext: RuntimeContext) = - runtimeContext(JsonField.of(runtimeContext)) + fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - @JsonProperty("runtime_context") - @ExcludeMissing - fun runtimeContext(runtimeContext: JsonField) = apply { - this.runtimeContext = runtimeContext + /** + * Sets [Builder.bundleId] to an arbitrary JSON value. + * + * You should usually call [Builder.bundleId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun bundleId(bundleId: JsonField) = apply { + this.bundleId = bundleId } - fun location(location: Location) = location(JsonField.of(location)) - - @JsonProperty("location") - @ExcludeMissing - fun location(location: JsonField) = apply { + fun location(location: CodeBundle.Location) = + location(JsonField.of(location)) + + /** + * Sets [Builder.location] to an arbitrary JSON value. + * + * You should usually call [Builder.location] with a well-typed + * [CodeBundle.Location] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun location(location: JsonField) = apply { this.location = location } - fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - - @JsonProperty("bundle_id") - @ExcludeMissing - fun bundleId(bundleId: JsonField) = apply { - this.bundleId = bundleId - } + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofExperiment(experiment)`. + */ + fun location(experiment: CodeBundle.Location.Experiment) = + location(CodeBundle.Location.ofExperiment(experiment)) + + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofFunction(function)`. + */ + fun location(function: CodeBundle.Location.Function) = + location(CodeBundle.Location.ofFunction(function)) + + fun runtimeContext(runtimeContext: CodeBundle.RuntimeContext) = + runtimeContext(JsonField.of(runtimeContext)) - /** A preview of the code */ - fun preview(preview: String) = preview(JsonField.of(preview)) + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [CodeBundle.RuntimeContext] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun runtimeContext(runtimeContext: JsonField) = + apply { + this.runtimeContext = runtimeContext + } /** A preview of the code */ - @JsonProperty("preview") - @ExcludeMissing + fun preview(preview: String?) = preview(JsonField.ofNullable(preview)) + + /** Alias for calling [Builder.preview] with `preview.orElse(null)`. */ + fun preview(preview: Optional) = preview(preview.getOrNull()) + + /** + * Sets [Builder.preview] to an arbitrary JSON value. + * + * You should usually call [Builder.preview] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun preview(preview: JsonField) = apply { this.preview = preview } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Bundle]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Bundle = Bundle( - runtimeContext, - location, - bundleId, + checkRequired("bundleId", bundleId), + checkRequired("location", location), + checkRequired("runtimeContext", runtimeContext), preview, - type, - additionalProperties.toUnmodifiable(), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } class Type @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val BUNDLE = Type(JsonField.of("bundle")) + @JvmField val BUNDLE = of("bundle") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - BUNDLE, + BUNDLE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { BUNDLE, + /** + * An enum member indicating that [Type] 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) { BUNDLE -> Value.BUNDLE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { BUNDLE -> Known.BUNDLE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Bundle && bundleId == other.bundleId && location == other.location && runtimeContext == other.runtimeContext && preview == other.preview && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(bundleId, location, runtimeContext, preview, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Bundle{bundleId=$bundleId, location=$location, runtimeContext=$runtimeContext, preview=$preview, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Inline.Builder::class) @NoAutoDetect class Inline + @JsonCreator private constructor( - private val type: JsonField, - private val runtimeContext: JsonField, - private val code: JsonField, - private val additionalProperties: Map, + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") - fun code(): String = code.getRequired("code") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext + fun _runtimeContext(): JsonField = runtimeContext - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Inline = apply { - if (!validated) { - type() - runtimeContext().validate() - code() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Inline = apply { + if (validated) { + return@apply } - return other is Inline && - this.type == other.type && - this.runtimeContext == other.runtimeContext && - this.code == other.code && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - runtimeContext, - code, - additionalProperties, - ) - } - return hashCode + code() + runtimeContext().validate() + type() + validated = true } - override fun toString() = - "Inline{type=$type, runtimeContext=$runtimeContext, code=$code, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Inline]. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Inline]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var runtimeContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() + private var code: JsonField? = null + private var runtimeContext: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inline: Inline) = apply { - this.type = inline.type - this.runtimeContext = inline.runtimeContext - this.code = inline.code - additionalProperties(inline.additionalProperties) + code = inline.code + runtimeContext = inline.runtimeContext + type = inline.type + additionalProperties = inline.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) + fun code(code: String) = code(JsonField.of(code)) - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } fun runtimeContext(runtimeContext: RuntimeContext) = runtimeContext(JsonField.of(runtimeContext)) - @JsonProperty("runtime_context") - @ExcludeMissing + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [RuntimeContext] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun runtimeContext(runtimeContext: JsonField) = apply { this.runtimeContext = runtimeContext } - fun code(code: String) = code(JsonField.of(code)) + fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Inline]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Inline = Inline( - type, - runtimeContext, - code, - additionalProperties.toUnmodifiable(), + checkRequired("code", code), + checkRequired("runtimeContext", runtimeContext), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = RuntimeContext.Builder::class) @NoAutoDetect class RuntimeContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime - - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("version") + @ExcludeMissing + fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RuntimeContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RuntimeContext = apply { + if (validated) { + return@apply } - return other is RuntimeContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [RuntimeContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RuntimeContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(runtimeContext: RuntimeContext) = apply { - this.runtime = runtimeContext.runtime - this.version = runtimeContext.version - additionalProperties(runtimeContext.additionalProperties) + runtime = runtimeContext.runtime + version = runtimeContext.version + additionalProperties = + runtimeContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } @@ -1484,67 +2477,106 @@ constructor( fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RuntimeContext]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RuntimeContext = RuntimeContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } class Runtime @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -1552,6 +2584,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value + * is a not a known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -1562,215 +2603,403 @@ constructor( ) } - fun asString(): String = _value().asStringOrThrow() - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is RuntimeContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + class Type + @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 INLINE = Type(JsonField.of("inline")) + @JvmField val INLINE = of("inline") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - INLINE, + INLINE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { INLINE, + /** + * An enum member indicating that [Type] 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) { INLINE -> Value.INLINE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { INLINE -> Known.INLINE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - return other is Type && this.value == other.value - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun hashCode() = value.hashCode() + return /* spotless:off */ other is Inline && code == other.code && runtimeContext == other.runtimeContext && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - override fun toString() = value.toString() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, runtimeContext, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Inline{code=$code, runtimeContext=$runtimeContext, type=$type, additionalProperties=$additionalProperties}" + } + } + + class Type @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 CODE = Type(JsonField.of("code")) + @JvmField val CODE = of("code") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - CODE, + CODE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { CODE, + /** + * An enum member indicating that [Type] was instantiated with an unknown value. + */ _UNKNOWN, } - fun value(): Value = - when (this) { - CODE -> Value.CODE - else -> 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) { + CODE -> Value.CODE + 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + CODE -> Known.CODE + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Code && data == other.data && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun known(): Known = - when (this) { - CODE -> Known.CODE - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, type, additionalProperties) } + /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun hashCode(): Int = hashCode + + override fun toString() = + "Code{data=$data, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1778,195 +3007,281 @@ constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" } } /** JSON schema for the function's parameters and return type */ - @JsonDeserialize(builder = FunctionSchema.Builder::class) @NoAutoDetect class FunctionSchema + @JsonCreator private constructor( - private val parameters: JsonValue?, - private val returns: JsonValue?, - private val additionalProperties: Map, + @JsonProperty("parameters") + @ExcludeMissing + private val parameters: JsonValue = JsonMissing.of(), + @JsonProperty("returns") @ExcludeMissing private val returns: JsonValue = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + @JsonProperty("parameters") @ExcludeMissing fun _parameters(): JsonValue = parameters - @JsonProperty("parameters") fun parameters(): JsonValue? = parameters - - @JsonProperty("returns") fun returns(): JsonValue? = returns + @JsonProperty("returns") @ExcludeMissing fun _returns(): JsonValue = returns @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionSchema = apply { + if (validated) { + return@apply } - return other is FunctionSchema && - this.parameters == other.parameters && - this.returns == other.returns && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - parameters, - returns, - additionalProperties, - ) - } - return hashCode + validated = true } - override fun toString() = - "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [FunctionSchema]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionSchema]. */ + class Builder internal constructor() { - private var parameters: JsonValue? = null - private var returns: JsonValue? = null + private var parameters: JsonValue = JsonMissing.of() + private var returns: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionSchema: FunctionSchema) = apply { - this.parameters = functionSchema.parameters - this.returns = functionSchema.returns - additionalProperties(functionSchema.additionalProperties) + parameters = functionSchema.parameters + returns = functionSchema.returns + additionalProperties = functionSchema.additionalProperties.toMutableMap() } - @JsonProperty("parameters") fun parameters(parameters: JsonValue) = apply { this.parameters = parameters } - @JsonProperty("returns") fun returns(returns: JsonValue) = apply { this.returns = returns } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionSchema = - FunctionSchema( - parameters, - returns, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [FunctionSchema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FunctionSchema = + FunctionSchema(parameters, returns, additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is FunctionType && this.value == other.value + return /* spotless:off */ other is FunctionSchema && parameters == other.parameters && returns == other.returns && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(parameters, returns, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + } + + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -1974,14 +3289,33 @@ constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -1991,6 +3325,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -2000,234 +3343,267 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - @JsonDeserialize(builder = Origin.Builder::class) @NoAutoDetect class Origin + @JsonCreator private constructor( - private val objectType: ObjectType?, - private val objectId: String?, - private val internal_: Boolean?, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("internal") + @ExcludeMissing + private val internal_: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * Id of the object the function is originating from + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** Id of the object the function is originating from */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") /** * The function exists for internal purposes and should not be displayed in the list of * functions. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun internal_(): Optional = Optional.ofNullable(internal_.getNullable("internal")) + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [internal_]. + * + * Unlike [internal_], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("internal") fun internal_(): Boolean? = internal_ + @JsonProperty("internal") @ExcludeMissing fun _internal_(): JsonField = internal_ @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Origin = apply { + if (validated) { + return@apply } - return other is Origin && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.internal_ == other.internal_ && - this.additionalProperties == other.additionalProperties + objectId() + objectType() + internal_() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - internal_, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Origin{objectType=$objectType, objectId=$objectId, internal_=$internal_, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Origin]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Origin]. */ + class Builder internal constructor() { - private var objectType: ObjectType? = null - private var objectId: String? = null - private var internal_: Boolean? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var internal_: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(origin: Origin) = apply { - this.objectType = origin.objectType - this.objectId = origin.objectId - this.internal_ = origin.internal_ - additionalProperties(origin.additionalProperties) + objectId = origin.objectId + objectType = origin.objectType + internal_ = origin.internal_ + additionalProperties = origin.additionalProperties.toMutableMap() } + /** Id of the object the function is originating from */ + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) - /** Id of the object the function is originating from */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * The function exists for internal purposes and should not be displayed in the list of * functions. */ - @JsonProperty("internal") - fun internal_(internal_: Boolean) = apply { this.internal_ = internal_ } + fun internal_(internal_: Boolean?) = internal_(JsonField.ofNullable(internal_)) + + /** + * Alias for [Builder.internal_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun internal_(internal_: Boolean) = internal_(internal_ as Boolean?) + + /** Alias for calling [Builder.internal_] with `internal_.orElse(null)`. */ + fun internal_(internal_: Optional) = internal_(internal_.getOrNull()) + + /** + * Sets [Builder.internal_] to an arbitrary JSON value. + * + * You should usually call [Builder.internal_] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun internal_(internal_: JsonField) = apply { this.internal_ = internal_ } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Origin]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Origin = Origin( - checkNotNull(objectType) { "`objectType` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), internal_, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + return /* spotless:off */ other is Origin && objectId == other.objectId && objectType == other.objectType && internal_ == other.internal_ && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, internal_, additionalProperties) } + /* spotless:on */ - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } + override fun hashCode(): Int = hashCode - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + override fun toString() = + "Origin{objectId=$objectId, objectType=$objectType, internal_=$internal_, additionalProperties=$additionalProperties}" + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is FunctionCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "FunctionCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionDeleteParams.kt index 3c433643..28d9eacc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a function object by its id */ class FunctionDeleteParams -constructor( +private constructor( private val functionId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Function id */ fun functionId(): String = functionId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is FunctionDeleteParams && - this.functionId == other.functionId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - functionId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "FunctionDeleteParams{functionId=$functionId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionDeleteParams]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var functionId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionDeleteParams: FunctionDeleteParams) = apply { - this.functionId = functionDeleteParams.functionId - additionalQueryParams(functionDeleteParams.additionalQueryParams) - additionalHeaders(functionDeleteParams.additionalHeaders) - additionalBodyProperties(functionDeleteParams.additionalBodyProperties) + functionId = functionDeleteParams.functionId + additionalHeaders = functionDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = functionDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = functionDeleteParams.additionalBodyProperties.toMutableMap() } /** Function id */ fun functionId(functionId: String) = apply { this.functionId = functionId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [FunctionDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionDeleteParams = FunctionDeleteParams( - checkNotNull(functionId) { "`functionId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("functionId", functionId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionDeleteParams && functionId == other.functionId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "FunctionDeleteParams{functionId=$functionId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeParams.kt index cc968e6e..407d29b9 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeParams.kt @@ -10,10 +10,15 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator @@ -27,51 +32,128 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Invoke a function. */ class FunctionInvokeParams -constructor( +private constructor( private val functionId: String, - private val input: JsonValue?, - private val messages: List?, - private val mode: Mode?, - private val parent: Parent?, - private val stream: Boolean?, - private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Function id */ fun functionId(): String = functionId - fun input(): Optional = Optional.ofNullable(input) - - fun messages(): Optional> = Optional.ofNullable(messages) - - fun mode(): Optional = Optional.ofNullable(mode) - - fun parent(): Optional = Optional.ofNullable(parent) - - fun stream(): Optional = Optional.ofNullable(stream) - - fun version(): Optional = Optional.ofNullable(version) - - @JvmSynthetic - internal fun getBody(): FunctionInvokeBody { - return FunctionInvokeBody( - input, - messages, - mode, - parent, - stream, - version, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** The expected output of the function */ + fun _expected(): JsonValue = body._expected() + + /** Argument to the function, which can be any JSON serializable value */ + fun _input(): JsonValue = body._input() + + /** + * If the function is an LLM, additional messages to pass along to it + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun messages(): Optional> = body.messages() + + /** + * Any relevant metadata + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = body.metadata() + + /** + * The mode format of the returned value (defaults to 'auto') + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun mode(): Optional = body.mode() + + /** + * Options for tracing the function call + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun parent(): Optional = body.parent() + + /** + * Whether to stream the response. If true, results will be returned in the Braintrust SSE + * format. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun stream(): Optional = body.stream() + + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = body.version() + + /** + * Returns the raw JSON value of [messages]. + * + * Unlike [messages], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _messages(): JsonField> = body._messages() + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _metadata(): JsonField = body._metadata() + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _mode(): JsonField = body._mode() + + /** + * Returns the raw JSON value of [parent]. + * + * Unlike [parent], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _parent(): JsonField = body._parent() + + /** + * Returns the raw JSON value of [stream]. + * + * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _stream(): JsonField = body._stream() + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _version(): JsonField = body._version() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -81,338 +163,677 @@ constructor( } /** The request to invoke a function */ - @JsonDeserialize(builder = FunctionInvokeBody.Builder::class) @NoAutoDetect - class FunctionInvokeBody - internal constructor( - private val input: JsonValue?, - private val messages: List?, - private val mode: Mode?, - private val parent: Parent?, - private val stream: Boolean?, - private val version: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("expected") + @ExcludeMissing + private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("messages") + @ExcludeMissing + private val messages: JsonField> = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("mode") @ExcludeMissing private val mode: JsonField = JsonMissing.of(), + @JsonProperty("parent") + @ExcludeMissing + private val parent: JsonField = JsonMissing.of(), + @JsonProperty("stream") + @ExcludeMissing + private val stream: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** The expected output of the function */ + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected /** Argument to the function, which can be any JSON serializable value */ - @JsonProperty("input") fun input(): JsonValue? = input + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input - /** If the function is an LLM, additional messages to pass along to it */ - @JsonProperty("messages") fun messages(): List? = messages + /** + * If the function is an LLM, additional messages to pass along to it + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun messages(): Optional> = + Optional.ofNullable(messages.getNullable("messages")) - /** The mode format of the returned value (defaults to 'auto') */ - @JsonProperty("mode") fun mode(): Mode? = mode + /** + * Any relevant metadata + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** Options for tracing the function call */ - @JsonProperty("parent") fun parent(): Parent? = parent + /** + * The mode format of the returned value (defaults to 'auto') + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun mode(): Optional = Optional.ofNullable(mode.getNullable("mode")) + + /** + * Options for tracing the function call + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun parent(): Optional = Optional.ofNullable(parent.getNullable("parent")) /** * Whether to stream the response. If true, results will be returned in the Braintrust SSE * format. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("stream") fun stream(): Boolean? = stream + fun stream(): Optional = Optional.ofNullable(stream.getNullable("stream")) - /** The version of the function */ - @JsonProperty("version") fun version(): String? = version + /** + * The version of the function + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [messages]. + * + * Unlike [messages], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("messages") + @ExcludeMissing + fun _messages(): JsonField> = messages + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [parent]. + * + * Unlike [parent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("parent") @ExcludeMissing fun _parent(): JsonField = parent + + /** + * Returns the raw JSON value of [stream]. + * + * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream") @ExcludeMissing fun _stream(): JsonField = stream + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is FunctionInvokeBody && - this.input == other.input && - this.messages == other.messages && - this.mode == other.mode && - this.parent == other.parent && - this.stream == other.stream && - this.version == other.version && - this.additionalProperties == other.additionalProperties + messages().ifPresent { it.forEach { it.validate() } } + metadata().ifPresent { it.validate() } + mode() + parent().ifPresent { it.validate() } + stream() + version() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - messages, - mode, - parent, - stream, - version, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "FunctionInvokeBody{input=$input, messages=$messages, mode=$mode, parent=$parent, stream=$stream, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var input: JsonValue? = null - private var messages: List? = null - private var mode: Mode? = null - private var parent: Parent? = null - private var stream: Boolean? = null - private var version: String? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var messages: JsonField>? = null + private var metadata: JsonField = JsonMissing.of() + private var mode: JsonField = JsonMissing.of() + private var parent: JsonField = JsonMissing.of() + private var stream: JsonField = JsonMissing.of() + private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(functionInvokeBody: FunctionInvokeBody) = apply { - this.input = functionInvokeBody.input - this.messages = functionInvokeBody.messages - this.mode = functionInvokeBody.mode - this.parent = functionInvokeBody.parent - this.stream = functionInvokeBody.stream - this.version = functionInvokeBody.version - additionalProperties(functionInvokeBody.additionalProperties) + internal fun from(body: Body) = apply { + expected = body.expected + input = body.input + messages = body.messages.map { it.toMutableList() } + metadata = body.metadata + mode = body.mode + parent = body.parent + stream = body.stream + version = body.version + additionalProperties = body.additionalProperties.toMutableMap() } + /** The expected output of the function */ + fun expected(expected: JsonValue) = apply { this.expected = expected } + /** Argument to the function, which can be any JSON serializable value */ - @JsonProperty("input") fun input(input: JsonValue) = apply { this.input = input } + fun input(input: JsonValue) = apply { this.input = input } /** If the function is an LLM, additional messages to pass along to it */ - @JsonProperty("messages") - fun messages(messages: List) = apply { this.messages = messages } + fun messages(messages: List) = messages(JsonField.of(messages)) + + /** + * Sets [Builder.messages] to an arbitrary JSON value. + * + * You should usually call [Builder.messages] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun messages(messages: JsonField>) = apply { + this.messages = messages.map { it.toMutableList() } + } + + /** + * Adds a single [Message] to [messages]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMessage(message: Message) = apply { + messages = + (messages ?: JsonField.of(mutableListOf())).also { + checkKnown("messages", it).add(message) + } + } + + /** Alias for calling [addMessage] with `Message.ofSystem(system)`. */ + fun addMessage(system: Message.System) = addMessage(Message.ofSystem(system)) + + /** Alias for calling [addMessage] with `Message.ofUser(user)`. */ + fun addMessage(user: Message.User) = addMessage(Message.ofUser(user)) + + /** Alias for calling [addMessage] with `Message.ofAssistant(assistant)`. */ + fun addMessage(assistant: Message.Assistant) = + addMessage(Message.ofAssistant(assistant)) + + /** Alias for calling [addMessage] with `Message.ofTool(tool)`. */ + fun addMessage(tool: Message.Tool) = addMessage(Message.ofTool(tool)) + + /** Alias for calling [addMessage] with `Message.ofFunction(function)`. */ + fun addMessage(function: Message.Function) = addMessage(Message.ofFunction(function)) + + /** Alias for calling [addMessage] with `Message.ofFallback(fallback)`. */ + fun addMessage(fallback: Message.Fallback) = addMessage(Message.ofFallback(fallback)) + + /** Any relevant metadata */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** The mode format of the returned value (defaults to 'auto') */ - @JsonProperty("mode") fun mode(mode: Mode) = apply { this.mode = mode } + fun mode(mode: Mode?) = mode(JsonField.ofNullable(mode)) + + /** Alias for calling [Builder.mode] with `mode.orElse(null)`. */ + fun mode(mode: Optional) = mode(mode.getOrNull()) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [Mode] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } /** Options for tracing the function call */ - @JsonProperty("parent") fun parent(parent: Parent) = apply { this.parent = parent } + fun parent(parent: Parent) = parent(JsonField.of(parent)) + + /** + * Sets [Builder.parent] to an arbitrary JSON value. + * + * You should usually call [Builder.parent] with a well-typed [Parent] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun parent(parent: JsonField) = apply { this.parent = parent } + + /** Alias for calling [parent] with `Parent.ofSpanParentStruct(spanParentStruct)`. */ + fun parent(spanParentStruct: Parent.SpanParentStruct) = + parent(Parent.ofSpanParentStruct(spanParentStruct)) + + /** Alias for calling [parent] with `Parent.ofString(string)`. */ + fun parent(string: String) = parent(Parent.ofString(string)) /** * Whether to stream the response. If true, results will be returned in the Braintrust * SSE format. */ - @JsonProperty("stream") fun stream(stream: Boolean) = apply { this.stream = stream } + fun stream(stream: Boolean?) = stream(JsonField.ofNullable(stream)) + + /** + * Alias for [Builder.stream]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun stream(stream: Boolean) = stream(stream as Boolean?) + + /** Alias for calling [Builder.stream] with `stream.orElse(null)`. */ + fun stream(stream: Optional) = stream(stream.getOrNull()) + + /** + * Sets [Builder.stream] to an arbitrary JSON value. + * + * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun stream(stream: JsonField) = apply { this.stream = stream } /** The version of the function */ - @JsonProperty("version") fun version(version: String) = apply { this.version = version } + fun version(version: String) = version(JsonField.of(version)) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionInvokeBody = - FunctionInvokeBody( + 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. + */ + fun build(): Body = + Body( + expected, input, - messages?.toUnmodifiable(), + (messages ?: JsonMissing.of()).map { it.toImmutable() }, + metadata, mode, parent, stream, version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && expected == other.expected && input == other.input && messages == other.messages && metadata == other.metadata && mode == other.mode && parent == other.parent && stream == other.stream && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is FunctionInvokeParams && - this.functionId == other.functionId && - this.input == other.input && - this.messages == other.messages && - this.mode == other.mode && - this.parent == other.parent && - this.stream == other.stream && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(expected, input, messages, metadata, mode, parent, stream, version, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - functionId, - input, - messages, - mode, - parent, - stream, - version, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "FunctionInvokeParams{functionId=$functionId, input=$input, messages=$messages, mode=$mode, parent=$parent, stream=$stream, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{expected=$expected, input=$input, messages=$messages, metadata=$metadata, mode=$mode, parent=$parent, stream=$stream, version=$version, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionInvokeParams]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionInvokeParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var functionId: String? = null - private var input: JsonValue? = null - private var messages: MutableList = mutableListOf() - private var mode: Mode? = null - private var parent: Parent? = null - private var stream: Boolean? = null - private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(functionInvokeParams: FunctionInvokeParams) = apply { - this.functionId = functionInvokeParams.functionId - this.input = functionInvokeParams.input - this.messages(functionInvokeParams.messages ?: listOf()) - this.mode = functionInvokeParams.mode - this.parent = functionInvokeParams.parent - this.stream = functionInvokeParams.stream - this.version = functionInvokeParams.version - additionalQueryParams(functionInvokeParams.additionalQueryParams) - additionalHeaders(functionInvokeParams.additionalHeaders) - additionalBodyProperties(functionInvokeParams.additionalBodyProperties) + functionId = functionInvokeParams.functionId + body = functionInvokeParams.body.toBuilder() + additionalHeaders = functionInvokeParams.additionalHeaders.toBuilder() + additionalQueryParams = functionInvokeParams.additionalQueryParams.toBuilder() } /** Function id */ fun functionId(functionId: String) = apply { this.functionId = functionId } + /** The expected output of the function */ + fun expected(expected: JsonValue) = apply { body.expected(expected) } + /** Argument to the function, which can be any JSON serializable value */ - fun input(input: JsonValue) = apply { this.input = input } + fun input(input: JsonValue) = apply { body.input(input) } /** If the function is an LLM, additional messages to pass along to it */ - fun messages(messages: List) = apply { - this.messages.clear() - this.messages.addAll(messages) - } + fun messages(messages: List) = apply { body.messages(messages) } - /** If the function is an LLM, additional messages to pass along to it */ - fun addMessage(message: Message) = apply { this.messages.add(message) } + /** + * Sets [Builder.messages] to an arbitrary JSON value. + * + * You should usually call [Builder.messages] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun messages(messages: JsonField>) = apply { body.messages(messages) } + + /** + * Adds a single [Message] to [messages]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMessage(message: Message) = apply { body.addMessage(message) } + + /** Alias for calling [addMessage] with `Message.ofSystem(system)`. */ + fun addMessage(system: Message.System) = apply { body.addMessage(system) } + + /** Alias for calling [addMessage] with `Message.ofUser(user)`. */ + fun addMessage(user: Message.User) = apply { body.addMessage(user) } + + /** Alias for calling [addMessage] with `Message.ofAssistant(assistant)`. */ + fun addMessage(assistant: Message.Assistant) = apply { body.addMessage(assistant) } + + /** Alias for calling [addMessage] with `Message.ofTool(tool)`. */ + fun addMessage(tool: Message.Tool) = apply { body.addMessage(tool) } + + /** Alias for calling [addMessage] with `Message.ofFunction(function)`. */ + fun addMessage(function: Message.Function) = apply { body.addMessage(function) } + + /** Alias for calling [addMessage] with `Message.ofFallback(fallback)`. */ + fun addMessage(fallback: Message.Fallback) = apply { body.addMessage(fallback) } + + /** Any relevant metadata */ + fun metadata(metadata: Metadata?) = apply { body.metadata(metadata) } + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** The mode format of the returned value (defaults to 'auto') */ - fun mode(mode: Mode) = apply { this.mode = mode } + fun mode(mode: Mode?) = apply { body.mode(mode) } - /** Options for tracing the function call */ - fun parent(parent: Parent) = apply { this.parent = parent } + /** Alias for calling [Builder.mode] with `mode.orElse(null)`. */ + fun mode(mode: Optional) = mode(mode.getOrNull()) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [Mode] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun mode(mode: JsonField) = apply { body.mode(mode) } /** Options for tracing the function call */ + fun parent(parent: Parent) = apply { body.parent(parent) } + + /** + * Sets [Builder.parent] to an arbitrary JSON value. + * + * You should usually call [Builder.parent] with a well-typed [Parent] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun parent(parent: JsonField) = apply { body.parent(parent) } + + /** Alias for calling [parent] with `Parent.ofSpanParentStruct(spanParentStruct)`. */ fun parent(spanParentStruct: Parent.SpanParentStruct) = apply { - this.parent = Parent.ofSpanParentStruct(spanParentStruct) + body.parent(spanParentStruct) } - /** Options for tracing the function call */ - fun parent(string: String) = apply { this.parent = Parent.ofString(string) } + /** Alias for calling [parent] with `Parent.ofString(string)`. */ + fun parent(string: String) = apply { body.parent(string) } /** * Whether to stream the response. If true, results will be returned in the Braintrust SSE * format. */ - fun stream(stream: Boolean) = apply { this.stream = stream } + fun stream(stream: Boolean?) = apply { body.stream(stream) } + + /** + * Alias for [Builder.stream]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun stream(stream: Boolean) = stream(stream as Boolean?) + + /** Alias for calling [Builder.stream] with `stream.orElse(null)`. */ + fun stream(stream: Optional) = stream(stream.getOrNull()) + + /** + * Sets [Builder.stream] to an arbitrary JSON value. + * + * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun stream(stream: JsonField) = apply { body.stream(stream) } /** The version of the function */ - fun version(version: String) = apply { this.version = version } + fun version(version: String) = apply { body.version(version) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { body.version(version) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [FunctionInvokeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionInvokeParams = FunctionInvokeParams( - checkNotNull(functionId) { "`functionId` is required but was not set" }, - input, - if (messages.size == 0) null else messages.toUnmodifiable(), - mode, - parent, - stream, - version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("functionId", functionId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -429,8 +850,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun system(): Optional = Optional.ofNullable(system) fun user(): Optional = Optional.ofNullable(user) @@ -481,26 +900,41 @@ constructor( } } + private var validated: Boolean = false + fun validate(): Message = apply { - if (!validated) { - if ( - system == null && - user == null && - assistant == null && - tool == null && - function == null && - fallback == null - ) { - throw BraintrustInvalidDataException("Unknown Message: $_json") - } - system?.validate() - user?.validate() - assistant?.validate() - tool?.validate() - function?.validate() - fallback?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitSystem(system: System) { + system.validate() + } + + override fun visitUser(user: User) { + user.validate() + } + + override fun visitAssistant(assistant: Assistant) { + assistant.validate() + } + + override fun visitTool(tool: Tool) { + tool.validate() + } + + override fun visitFunction(function: Function) { + function.validate() + } + + override fun visitFallback(fallback: Fallback) { + fallback.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -508,28 +942,13 @@ constructor( return true } - return other is Message && - this.system == other.system && - this.user == other.user && - this.assistant == other.assistant && - this.tool == other.tool && - this.function == other.function && - this.fallback == other.fallback + return /* spotless:off */ other is Message && system == other.system && user == other.user && assistant == other.assistant && tool == other.tool && function == other.function && fallback == other.fallback /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - system, - user, - assistant, - tool, - function, - fallback, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(system, user, assistant, tool, function, fallback) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { system != null -> "Message{system=$system}" user != null -> "Message{user=$user}" assistant != null -> "Message{assistant=$assistant}" @@ -539,7 +958,6 @@ constructor( _json != null -> "Message{_unknown=$_json}" else -> throw IllegalStateException("Invalid Message") } - } companion object { @@ -556,6 +974,9 @@ constructor( @JvmStatic fun ofFallback(fallback: Fallback) = Message(fallback = fallback) } + /** + * An interface that defines how to map each variant of [Message] to a value of type [T]. + */ interface Visitor { fun visitSystem(system: System): T @@ -570,15 +991,26 @@ constructor( fun visitFallback(fallback: Fallback): T + /** + * Maps an unknown variant of [Message] to a value of type [T]. + * + * An instance of [Message] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Message: $json") } } - class Deserializer : BaseDeserializer(Message::class) { + internal class Deserializer : BaseDeserializer(Message::class) { override fun ObjectCodec.deserialize(node: JsonNode): Message { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Message(system = it, _json = json) @@ -608,12 +1040,12 @@ constructor( } } - class Serializer : BaseSerializer(Message::class) { + internal class Serializer : BaseSerializer(Message::class) { override fun serialize( value: Message, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.system != null -> generator.writeObject(value.system) @@ -628,121 +1060,151 @@ constructor( } } - @JsonDeserialize(builder = System.Builder::class) @NoAutoDetect class System + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - @JsonProperty("content") @ExcludeMissing fun _content() = content - - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): System = apply { - if (!validated) { - content() - role() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): System = apply { + if (validated) { + return@apply } - return other is System && - this.content == other.content && - this.role == other.role && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - name, - additionalProperties, - ) - } - return hashCode + role() + content() + name() + validated = true } - override fun toString() = - "System{content=$content, role=$role, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [System]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [System]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(system: System) = apply { - this.content = system.content - this.role = system.role - this.name = system.name - additionalProperties(system.additionalProperties) + role = system.role + content = system.content + name = system.name + additionalProperties = system.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -750,182 +1212,302 @@ constructor( 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 [System]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): System = System( + checkRequired("role", role), content, - role, name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val SYSTEM = Role(JsonField.of("system")) + @JvmField val SYSTEM = of("system") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - SYSTEM, + SYSTEM } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { SYSTEM, + /** + * An enum member indicating that [Role] 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) { SYSTEM -> Value.SYSTEM 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { SYSTEM -> Known.SYSTEM else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is System && role == other.role && content == other.content && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "System{role=$role, content=$content, name=$name, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = User.Builder::class) @NoAutoDetect class User + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): User = apply { - if (!validated) { - content() - role() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): User = apply { + if (validated) { + return@apply } - return other is User && - this.content == other.content && - this.role == other.role && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - name, - additionalProperties, - ) - } - return hashCode + role() + content().ifPresent { it.validate() } + name() + validated = true } - override fun toString() = - "User{content=$content, role=$role, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [User]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [User]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(user: User) = apply { - this.content = user.content - this.role = user.role - this.name = user.name - additionalProperties(user.additionalProperties) + role = user.role + content = user.content + name = user.name + additionalProperties = user.additionalProperties.toMutableMap() } + fun role(role: Role) = role(JsonField.of(role)) + + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun role(role: JsonField) = apply { this.role = role } + fun content(content: Content) = content(JsonField.of(content)) - @JsonProperty("content") - @ExcludeMissing + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) + /** Alias for calling [content] with `Content.ofText(text)`. */ + fun content(text: String) = content(Content.ofText(text)) - @JsonProperty("role") - @ExcludeMissing - fun role(role: JsonField) = apply { this.role = role } + /** Alias for calling [content] with `Content.ofArray(array)`. */ + fun contentOfArray(array: List) = + content(Content.ofArray(array)) fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -933,109 +1515,180 @@ constructor( 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 [User]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): User = User( + checkRequired("role", role), content, - role, name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val USER = Role(JsonField.of("user")) + @JvmField val USER = of("user") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - USER, + USER } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { USER, + /** + * An enum member indicating that [Role] 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) { USER -> Value.USER 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { USER -> Known.USER else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } @JsonDeserialize(using = Content.Deserializer::class) @JsonSerialize(using = Content.Serializer::class) class Content private constructor( - private val string: String? = null, - private val chatCompletionContentParts: List? = null, + private val text: String? = null, + private val array: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - - fun string(): Optional = Optional.ofNullable(string) + fun text(): Optional = Optional.ofNullable(text) - fun chatCompletionContentParts(): Optional> = - Optional.ofNullable(chatCompletionContentParts) + fun array(): Optional> = Optional.ofNullable(array) - fun isString(): Boolean = string != null + fun isText(): Boolean = text != null - fun isChatCompletionContentParts(): Boolean = chatCompletionContentParts != null + fun isArray(): Boolean = array != null - fun asString(): String = string.getOrThrow("string") + fun asText(): String = text.getOrThrow("text") - fun asChatCompletionContentParts(): List = - chatCompletionContentParts.getOrThrow("chatCompletionContentParts") + fun asArray(): List = array.getOrThrow("array") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - string != null -> visitor.visitString(string) - chatCompletionContentParts != null -> - visitor.visitChatCompletionContentParts(chatCompletionContentParts) + text != null -> visitor.visitText(text) + array != null -> visitor.visitArray(array) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Content = apply { - if (!validated) { - if (string == null && chatCompletionContentParts == null) { - throw BraintrustInvalidDataException("Unknown Content: $_json") - } - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitText(text: String) {} + + override fun visitArray(array: List) { + array.forEach { it.validate() } + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -1043,75 +1696,81 @@ constructor( return true } - return other is Content && - this.string == other.string && - this.chatCompletionContentParts == other.chatCompletionContentParts + return /* spotless:off */ other is Content && text == other.text && array == other.array /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, chatCompletionContentParts) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(text, array) /* spotless:on */ - override fun toString(): String { - return when { - string != null -> "Content{string=$string}" - chatCompletionContentParts != null -> - "Content{chatCompletionContentParts=$chatCompletionContentParts}" + override fun toString(): String = + when { + text != null -> "Content{text=$text}" + array != null -> "Content{array=$array}" _json != null -> "Content{_unknown=$_json}" else -> throw IllegalStateException("Invalid Content") } - } companion object { - @JvmStatic fun ofString(string: String) = Content(string = string) + @JvmStatic fun ofText(text: String) = Content(text = text) @JvmStatic - fun ofChatCompletionContentParts( - chatCompletionContentParts: List - ) = Content(chatCompletionContentParts = chatCompletionContentParts) + fun ofArray(array: List) = Content(array = array) } + /** + * An interface that defines how to map each variant of [Content] to a value of type + * [T]. + */ interface Visitor { - fun visitString(string: String): T + fun visitText(text: String): T - fun visitChatCompletionContentParts( - chatCompletionContentParts: List - ): T + fun visitArray(array: List): T + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Content: $json") } } - class Deserializer : BaseDeserializer(Content::class) { + internal class Deserializer : BaseDeserializer(Content::class) { override fun ObjectCodec.deserialize(node: JsonNode): Content { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { - return Content(string = it, _json = json) + return Content(text = it, _json = json) } - tryDeserialize(node, jacksonTypeRef>()) + tryDeserialize(node, jacksonTypeRef>()) { + it.forEach { it.validate() } + } ?.let { - return Content(chatCompletionContentParts = it, _json = json) + return Content(array = it, _json = json) } return Content(_json = json) } } - class Serializer : BaseSerializer(Content::class) { + internal class Serializer : BaseSerializer(Content::class) { override fun serialize( value: Content, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.string != null -> generator.writeObject(value.string) - value.chatCompletionContentParts != null -> - generator.writeObject(value.chatCompletionContentParts) + value.text != null -> generator.writeObject(value.text) + value.array != null -> generator.writeObject(value.array) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Content") } @@ -1122,63 +1781,53 @@ constructor( @JsonSerialize(using = ChatCompletionContentPart.Serializer::class) class ChatCompletionContentPart private constructor( - private val chatCompletionContentPartText: ChatCompletionContentPartText? = - null, - private val chatCompletionContentPartImage: ChatCompletionContentPartImage? = - null, + private val text: ChatCompletionContentPartText? = null, + private val image: ChatCompletionContentPartImage? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - - fun chatCompletionContentPartText(): Optional = - Optional.ofNullable(chatCompletionContentPartText) + fun text(): Optional = Optional.ofNullable(text) - fun chatCompletionContentPartImage(): Optional = - Optional.ofNullable(chatCompletionContentPartImage) + fun image(): Optional = + Optional.ofNullable(image) - fun isChatCompletionContentPartText(): Boolean = - chatCompletionContentPartText != null + fun isText(): Boolean = text != null - fun isChatCompletionContentPartImage(): Boolean = - chatCompletionContentPartImage != null + fun isImage(): Boolean = image != null - fun asChatCompletionContentPartText(): ChatCompletionContentPartText = - chatCompletionContentPartText.getOrThrow("chatCompletionContentPartText") + fun asText(): ChatCompletionContentPartText = text.getOrThrow("text") - fun asChatCompletionContentPartImage(): ChatCompletionContentPartImage = - chatCompletionContentPartImage.getOrThrow("chatCompletionContentPartImage") + fun asImage(): ChatCompletionContentPartImage = image.getOrThrow("image") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - chatCompletionContentPartText != null -> - visitor.visitChatCompletionContentPartText( - chatCompletionContentPartText - ) - chatCompletionContentPartImage != null -> - visitor.visitChatCompletionContentPartImage( - chatCompletionContentPartImage - ) + text != null -> visitor.visitText(text) + image != null -> visitor.visitImage(image) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): ChatCompletionContentPart = apply { - if (!validated) { - if ( - chatCompletionContentPartText == null && - chatCompletionContentPartImage == null - ) { - throw BraintrustInvalidDataException( - "Unknown ChatCompletionContentPart: $_json" - ) - } - chatCompletionContentPartText?.validate() - chatCompletionContentPartImage?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitText(text: ChatCompletionContentPartText) { + text.validate() + } + + override fun visitImage(image: ChatCompletionContentPartImage) { + image.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -1186,60 +1835,51 @@ constructor( return true } - return other is ChatCompletionContentPart && - this.chatCompletionContentPartText == - other.chatCompletionContentPartText && - this.chatCompletionContentPartImage == - other.chatCompletionContentPartImage + return /* spotless:off */ other is ChatCompletionContentPart && text == other.text && image == other.image /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - chatCompletionContentPartText, - chatCompletionContentPartImage - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(text, image) /* spotless:on */ - override fun toString(): String { - return when { - chatCompletionContentPartText != null -> - "ChatCompletionContentPart{chatCompletionContentPartText=$chatCompletionContentPartText}" - chatCompletionContentPartImage != null -> - "ChatCompletionContentPart{chatCompletionContentPartImage=$chatCompletionContentPartImage}" + override fun toString(): String = + when { + text != null -> "ChatCompletionContentPart{text=$text}" + image != null -> "ChatCompletionContentPart{image=$image}" _json != null -> "ChatCompletionContentPart{_unknown=$_json}" else -> throw IllegalStateException("Invalid ChatCompletionContentPart") } - } companion object { @JvmStatic - fun ofChatCompletionContentPartText( - chatCompletionContentPartText: ChatCompletionContentPartText - ) = - ChatCompletionContentPart( - chatCompletionContentPartText = chatCompletionContentPartText - ) + fun ofText(text: ChatCompletionContentPartText) = + ChatCompletionContentPart(text = text) @JvmStatic - fun ofChatCompletionContentPartImage( - chatCompletionContentPartImage: ChatCompletionContentPartImage - ) = - ChatCompletionContentPart( - chatCompletionContentPartImage = chatCompletionContentPartImage - ) + fun ofImage(image: ChatCompletionContentPartImage) = + ChatCompletionContentPart(image = image) } + /** + * An interface that defines how to map each variant of + * [ChatCompletionContentPart] to a value of type [T]. + */ interface Visitor { - fun visitChatCompletionContentPartText( - chatCompletionContentPartText: ChatCompletionContentPartText - ): T - - fun visitChatCompletionContentPartImage( - chatCompletionContentPartImage: ChatCompletionContentPartImage - ): T - + fun visitText(text: ChatCompletionContentPartText): T + + fun visitImage(image: ChatCompletionContentPartImage): T + + /** + * Maps an unknown variant of [ChatCompletionContentPart] to a value of type + * [T]. + * + * An instance of [ChatCompletionContentPart] can contain an unknown variant + * if it was deserialized from data that doesn't match any known variant. + * For example, if the SDK is on an older version than the API, then the API + * may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException( "Unknown ChatCompletionContentPart: $json" @@ -1247,7 +1887,7 @@ constructor( } } - class Deserializer : + internal class Deserializer : BaseDeserializer( ChatCompletionContentPart::class ) { @@ -1256,30 +1896,25 @@ constructor( node: JsonNode ): ChatCompletionContentPart { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return ChatCompletionContentPart( - chatCompletionContentPartText = it, - _json = json - ) + return ChatCompletionContentPart(text = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { - return ChatCompletionContentPart( - chatCompletionContentPartImage = it, - _json = json - ) + return ChatCompletionContentPart(image = it, _json = json) } return ChatCompletionContentPart(_json = json) } } - class Serializer : + internal class Serializer : BaseSerializer( ChatCompletionContentPart::class ) { @@ -1287,13 +1922,11 @@ constructor( override fun serialize( value: ChatCompletionContentPart, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.chatCompletionContentPartText != null -> - generator.writeObject(value.chatCompletionContentPartText) - value.chatCompletionContentPartImage != null -> - generator.writeObject(value.chatCompletionContentPartImage) + value.text != null -> generator.writeObject(value.text) + value.image != null -> generator.writeObject(value.image) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid ChatCompletionContentPart") @@ -1302,164 +1935,271 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is User && role == other.role && content == other.content && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "User{role=$role, content=$content, name=$name, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Assistant.Builder::class) @NoAutoDetect class Assistant + @JsonCreator private constructor( - private val role: JsonField, - private val content: JsonField, - private val functionCall: JsonField, - private val name: JsonField, - private val toolCalls: JsonField>, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("function_call") + @ExcludeMissing + private val functionCall: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("tool_calls") + @ExcludeMissing + private val toolCalls: JsonField> = + JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun functionCall(): Optional = Optional.ofNullable(functionCall.getNullable("function_call")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun toolCalls(): Optional> = Optional.ofNullable(toolCalls.getNullable("tool_calls")) - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content - @JsonProperty("function_call") @ExcludeMissing fun _functionCall() = functionCall + /** + * Returns the raw JSON value of [functionCall]. + * + * Unlike [functionCall], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_call") + @ExcludeMissing + fun _functionCall(): JsonField = functionCall - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 - @JsonProperty("tool_calls") @ExcludeMissing fun _toolCalls() = toolCalls + /** + * Returns the raw JSON value of [toolCalls]. + * + * Unlike [toolCalls], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("tool_calls") + @ExcludeMissing + fun _toolCalls(): JsonField> = toolCalls @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Assistant = apply { - if (!validated) { - role() - content() - functionCall().map { it.validate() } - name() - toolCalls().map { it.forEach { it.validate() } } - validated = true + if (validated) { + return@apply } + + role() + content() + functionCall().ifPresent { it.validate() } + name() + toolCalls().ifPresent { it.forEach { it.validate() } } + validated = true } fun toBuilder() = Builder().from(this) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Assistant && - this.role == other.role && - this.content == other.content && - this.functionCall == other.functionCall && - this.name == other.name && - this.toolCalls == other.toolCalls && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - role, - content, - functionCall, - name, - toolCalls, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Assistant{role=$role, content=$content, functionCall=$functionCall, name=$name, toolCalls=$toolCalls, additionalProperties=$additionalProperties}" - - companion object { + companion object { + /** + * Returns a mutable builder for constructing an instance of [Assistant]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Assistant]. */ + class Builder internal constructor() { - private var role: JsonField = JsonMissing.of() + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() private var functionCall: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() - private var toolCalls: JsonField> = - JsonMissing.of() + private var toolCalls: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(assistant: Assistant) = apply { - this.role = assistant.role - this.content = assistant.content - this.functionCall = assistant.functionCall - this.name = assistant.name - this.toolCalls = assistant.toolCalls - additionalProperties(assistant.additionalProperties) + role = assistant.role + content = assistant.content + functionCall = assistant.functionCall + name = assistant.name + toolCalls = assistant.toolCalls.map { it.toMutableList() } + additionalProperties = assistant.additionalProperties.toMutableMap() } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun role(role: JsonField) = apply { this.role = role } - fun content(content: String) = content(JsonField.of(content)) + fun content(content: String?) = content(JsonField.ofNullable(content)) - @JsonProperty("content") - @ExcludeMissing + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } - fun functionCall(functionCall: FunctionCall) = - functionCall(JsonField.of(functionCall)) + fun functionCall(functionCall: FunctionCall?) = + functionCall(JsonField.ofNullable(functionCall)) - @JsonProperty("function_call") - @ExcludeMissing + /** Alias for calling [Builder.functionCall] with `functionCall.orElse(null)`. */ + fun functionCall(functionCall: Optional) = + functionCall(functionCall.getOrNull()) + + /** + * Sets [Builder.functionCall] to an arbitrary JSON value. + * + * You should usually call [Builder.functionCall] with a well-typed [FunctionCall] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ fun functionCall(functionCall: JsonField) = apply { this.functionCall = functionCall } - fun name(name: String) = name(JsonField.of(name)) + fun name(name: String?) = name(JsonField.ofNullable(name)) - @JsonProperty("name") - @ExcludeMissing + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } - fun toolCalls(toolCalls: List) = - toolCalls(JsonField.of(toolCalls)) + fun toolCalls(toolCalls: List?) = + toolCalls(JsonField.ofNullable(toolCalls)) - @JsonProperty("tool_calls") - @ExcludeMissing + /** Alias for calling [Builder.toolCalls] with `toolCalls.orElse(null)`. */ + fun toolCalls(toolCalls: Optional>) = + toolCalls(toolCalls.getOrNull()) + + /** + * Sets [Builder.toolCalls] to an arbitrary JSON value. + * + * You should usually call [Builder.toolCalls] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ fun toolCalls(toolCalls: JsonField>) = apply { - this.toolCalls = toolCalls + this.toolCalls = toolCalls.map { it.toMutableList() } + } + + /** + * Adds a single [ChatCompletionMessageToolCall] to [toolCalls]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addToolCall(toolCall: ChatCompletionMessageToolCall) = apply { + toolCalls = + (toolCalls ?: JsonField.of(mutableListOf())).also { + checkKnown("toolCalls", it).add(toolCall) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1467,169 +2207,257 @@ constructor( 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 [Assistant]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Assistant = Assistant( - role, + checkRequired("role", role), content, functionCall, name, - toolCalls.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + (toolCalls ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val ASSISTANT = Role(JsonField.of("assistant")) + @JvmField val ASSISTANT = of("assistant") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - ASSISTANT, + ASSISTANT } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { ASSISTANT, + /** + * An enum member indicating that [Role] 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) { ASSISTANT -> Value.ASSISTANT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { ASSISTANT -> Known.ASSISTANT else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - @JsonDeserialize(builder = FunctionCall.Builder::class) @NoAutoDetect class FunctionCall + @JsonCreator private constructor( - private val arguments: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("arguments") + @ExcludeMissing + private val arguments: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 arguments(): String = arguments.getRequired("arguments") + /** + * @throws BraintrustInvalidDataException 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") - @JsonProperty("arguments") @ExcludeMissing fun _arguments() = arguments + /** + * Returns the raw JSON value of [arguments]. + * + * Unlike [arguments], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("arguments") + @ExcludeMissing + fun _arguments(): JsonField = arguments - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FunctionCall = apply { - if (!validated) { - arguments() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionCall = apply { + if (validated) { + return@apply } - return other is FunctionCall && - this.arguments == other.arguments && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - arguments, - name, - additionalProperties, - ) - } - return hashCode + arguments() + name() + validated = true } - override fun toString() = - "FunctionCall{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionCall]. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionCall]. */ + class Builder internal constructor() { - private var arguments: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var arguments: JsonField? = null + private var name: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionCall: FunctionCall) = apply { - this.arguments = functionCall.arguments - this.name = functionCall.name - additionalProperties(functionCall.additionalProperties) + arguments = functionCall.arguments + name = functionCall.name + additionalProperties = functionCall.additionalProperties.toMutableMap() } fun arguments(arguments: String) = arguments(JsonField.of(arguments)) - @JsonProperty("arguments") - @ExcludeMissing + /** + * Sets [Builder.arguments] to an arbitrary JSON value. + * + * You should usually call [Builder.arguments] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ fun arguments(arguments: JsonField) = apply { this.arguments = arguments } fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1637,134 +2465,222 @@ constructor( 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 [FunctionCall]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionCall = FunctionCall( - arguments, - name, - additionalProperties.toUnmodifiable(), + checkRequired("arguments", arguments), + checkRequired("name", name), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionCall && arguments == other.arguments && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(arguments, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCall{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Assistant && role == other.role && content == other.content && functionCall == other.functionCall && name == other.name && toolCalls == other.toolCalls && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, functionCall, name, toolCalls, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Assistant{role=$role, content=$content, functionCall=$functionCall, name=$name, toolCalls=$toolCalls, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Tool.Builder::class) @NoAutoDetect class Tool + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val toolCallId: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("tool_call_id") + @ExcludeMissing + private val toolCallId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun toolCallId(): Optional = Optional.ofNullable(toolCallId.getNullable("tool_call_id")) - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content - @JsonProperty("tool_call_id") @ExcludeMissing fun _toolCallId() = toolCallId + /** + * Returns the raw JSON value of [toolCallId]. + * + * Unlike [toolCallId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("tool_call_id") + @ExcludeMissing + fun _toolCallId(): JsonField = toolCallId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Tool = apply { - if (!validated) { - content() - role() - toolCallId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Tool = apply { + if (validated) { + return@apply } - return other is Tool && - this.content == other.content && - this.role == other.role && - this.toolCallId == other.toolCallId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - toolCallId, - additionalProperties, - ) - } - return hashCode + role() + content() + toolCallId() + validated = true } - override fun toString() = - "Tool{content=$content, role=$role, toolCallId=$toolCallId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Tool]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Tool]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var toolCallId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(tool: Tool) = apply { - this.content = tool.content - this.role = tool.role - this.toolCallId = tool.toolCallId - additionalProperties(tool.additionalProperties) + role = tool.role + content = tool.content + toolCallId = tool.toolCallId + additionalProperties = tool.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun toolCallId(toolCallId: String) = toolCallId(JsonField.of(toolCallId)) - @JsonProperty("tool_call_id") - @ExcludeMissing + /** + * Sets [Builder.toolCallId] to an arbitrary JSON value. + * + * You should usually call [Builder.toolCallId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun toolCallId(toolCallId: JsonField) = apply { this.toolCallId = toolCallId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1772,182 +2688,297 @@ constructor( 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 [Tool]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Tool = Tool( + checkRequired("role", role), content, - role, toolCallId, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val TOOL = Role(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - TOOL, + TOOL } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { TOOL, + /** + * An enum member indicating that [Role] 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) { TOOL -> Value.TOOL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { TOOL -> Known.TOOL else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Tool && role == other.role && content == other.content && toolCallId == other.toolCallId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, toolCallId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Tool{role=$role, content=$content, toolCallId=$toolCallId, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val content: JsonField, - private val name: JsonField, - private val role: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - content() - name() - role() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.content == other.content && - this.name == other.name && - this.role == other.role && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - name, - role, - additionalProperties, - ) - } - return hashCode + name() + role() + content() + validated = true } - override fun toString() = - "Function{content=$content, name=$name, role=$role, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .name() + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { + private var name: JsonField? = null + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.content = function.content - this.name = function.name - this.role = function.role - additionalProperties(function.additionalProperties) + name = function.name + role = function.role + content = function.content + additionalProperties = function.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1955,166 +2986,269 @@ constructor( 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( + checkRequired("name", name), + checkRequired("role", role), content, - name, - role, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val FUNCTION = Role(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { FUNCTION, + /** + * An enum member indicating that [Role] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && name == other.name && role == other.role && content == other.content && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, role, content, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{name=$name, role=$role, content=$content, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Fallback.Builder::class) @NoAutoDetect class Fallback + @JsonCreator private constructor( - private val role: JsonField, - private val content: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Fallback = apply { - if (!validated) { - role() - content() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Fallback = apply { + if (validated) { + return@apply } - return other is Fallback && - this.role == other.role && - this.content == other.content && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - role, - content, - additionalProperties, - ) - } - return hashCode + role() + content() + validated = true } - override fun toString() = - "Fallback{role=$role, content=$content, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Fallback]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Fallback]. */ + class Builder internal constructor() { - private var role: JsonField = JsonMissing.of() + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(fallback: Fallback) = apply { - this.role = fallback.role - this.content = fallback.content - additionalProperties(fallback.additionalProperties) + role = fallback.role + content = fallback.content + additionalProperties = fallback.additionalProperties.toMutableMap() } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun role(role: JsonField) = apply { this.role = role } - fun content(content: String) = content(JsonField.of(content)) + fun content(content: String?) = content(JsonField.ofNullable(content)) - @JsonProperty("content") - @ExcludeMissing + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2122,107 +3256,286 @@ constructor( 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 [Fallback]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Fallback = Fallback( - role, + checkRequired("role", role), content, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Role - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Role @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val MODEL = Role(JsonField.of("model")) + @JvmField val MODEL = of("model") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - MODEL, + MODEL } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Role] 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 { MODEL, + /** + * An enum member indicating that [Role] 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) { MODEL -> Value.MODEL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { MODEL -> Known.MODEL else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Fallback && role == other.role && content == other.content && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Fallback{role=$role, content=$content, additionalProperties=$additionalProperties}" } } - class Mode + /** Any relevant metadata */ + @NoAutoDetect + class Metadata @JsonCreator private constructor( - private val value: JsonField, - ) : Enum { + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Mode && this.value == other.value + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + /** The mode format of the returned value (defaults to 'auto') */ + class Mode @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 AUTO = Mode(JsonField.of("auto")) + @JvmField val AUTO = of("auto") - @JvmField val PARALLEL = Mode(JsonField.of("parallel")) + @JvmField val PARALLEL = of("parallel") @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) } + /** An enum containing [Mode]'s known values. */ enum class Known { AUTO, PARALLEL, } + /** + * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Mode] 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 { AUTO, PARALLEL, + /** An enum member indicating that [Mode] 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) { AUTO -> Value.AUTO @@ -2230,6 +3543,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { AUTO -> Known.AUTO @@ -2237,9 +3559,34 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown Mode: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Mode && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + /** Options for tracing the function call */ @JsonDeserialize(using = Parent.Deserializer::class) @JsonSerialize(using = Parent.Serializer::class) class Parent @@ -2249,10 +3596,9 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** Span parent properties */ fun spanParentStruct(): Optional = Optional.ofNullable(spanParentStruct) + /** The parent's span identifier, created by calling `.export()` on a span */ fun string(): Optional = Optional.ofNullable(string) @@ -2260,8 +3606,10 @@ constructor( fun isString(): Boolean = string != null + /** Span parent properties */ fun asSpanParentStruct(): SpanParentStruct = spanParentStruct.getOrThrow("spanParentStruct") + /** The parent's span identifier, created by calling `.export()` on a span */ fun asString(): String = string.getOrThrow("string") fun _json(): Optional = Optional.ofNullable(_json) @@ -2274,14 +3622,23 @@ constructor( } } + private var validated: Boolean = false + fun validate(): Parent = apply { - if (!validated) { - if (spanParentStruct == null && string == null) { - throw BraintrustInvalidDataException("Unknown Parent: $_json") - } - spanParentStruct?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitSpanParentStruct(spanParentStruct: SpanParentStruct) { + spanParentStruct.validate() + } + + override fun visitString(string: String) {} + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -2289,48 +3646,59 @@ constructor( return true } - return other is Parent && - this.spanParentStruct == other.spanParentStruct && - this.string == other.string + return /* spotless:off */ other is Parent && spanParentStruct == other.spanParentStruct && string == other.string /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(spanParentStruct, string) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanParentStruct, string) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { spanParentStruct != null -> "Parent{spanParentStruct=$spanParentStruct}" string != null -> "Parent{string=$string}" _json != null -> "Parent{_unknown=$_json}" else -> throw IllegalStateException("Invalid Parent") } - } companion object { + /** Span parent properties */ @JvmStatic fun ofSpanParentStruct(spanParentStruct: SpanParentStruct) = Parent(spanParentStruct = spanParentStruct) + /** The parent's span identifier, created by calling `.export()` on a span */ @JvmStatic fun ofString(string: String) = Parent(string = string) } + /** An interface that defines how to map each variant of [Parent] to a value of type [T]. */ interface Visitor { + /** Span parent properties */ fun visitSpanParentStruct(spanParentStruct: SpanParentStruct): T + /** The parent's span identifier, created by calling `.export()` on a span */ fun visitString(string: String): T + /** + * Maps an unknown variant of [Parent] to a value of type [T]. + * + * An instance of [Parent] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Parent: $json") } } - class Deserializer : BaseDeserializer(Parent::class) { + internal class Deserializer : BaseDeserializer(Parent::class) { override fun ObjectCodec.deserialize(node: JsonNode): Parent { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Parent(spanParentStruct = it, _json = json) @@ -2343,12 +3711,12 @@ constructor( } } - class Serializer : BaseSerializer(Parent::class) { + internal class Serializer : BaseSerializer(Parent::class) { override fun serialize( value: Parent, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.spanParentStruct != null -> generator.writeObject(value.spanParentStruct) @@ -2360,157 +3728,214 @@ constructor( } /** Span parent properties */ - @JsonDeserialize(builder = SpanParentStruct.Builder::class) @NoAutoDetect class SpanParentStruct + @JsonCreator private constructor( - private val objectType: JsonField, - private val objectId: JsonField, - private val rowIds: JsonField, - private val propagatedEvent: JsonField, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("propagated_event") + @ExcludeMissing + private val propagatedEvent: JsonField = JsonMissing.of(), + @JsonProperty("row_ids") + @ExcludeMissing + private val rowIds: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun objectType(): ObjectType = objectType.getRequired("object_type") - - /** The id of the container object you are logging to */ + /** + * The id of the container object you are logging to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** Identifiers for the row to to log a subspan under */ - fun rowIds(): Optional = Optional.ofNullable(rowIds.getNullable("row_ids")) + /** + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") - /** Include these properties in every span created under this parent */ + /** + * Include these properties in every span created under this parent + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun propagatedEvent(): Optional = Optional.ofNullable(propagatedEvent.getNullable("propagated_event")) - @JsonProperty("object_type") @ExcludeMissing fun _objectType() = objectType + /** + * Identifiers for the row to to log a subspan under + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun rowIds(): Optional = Optional.ofNullable(rowIds.getNullable("row_ids")) - /** The id of the container object you are logging to */ - @JsonProperty("object_id") @ExcludeMissing fun _objectId() = objectId + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId - /** Identifiers for the row to to log a subspan under */ - @JsonProperty("row_ids") @ExcludeMissing fun _rowIds() = rowIds + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType - /** Include these properties in every span created under this parent */ + /** + * Returns the raw JSON value of [propagatedEvent]. + * + * Unlike [propagatedEvent], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("propagated_event") @ExcludeMissing - fun _propagatedEvent() = propagatedEvent + fun _propagatedEvent(): JsonField = propagatedEvent + + /** + * Returns the raw JSON value of [rowIds]. + * + * Unlike [rowIds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("row_ids") @ExcludeMissing fun _rowIds(): JsonField = rowIds @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): SpanParentStruct = apply { - if (!validated) { - objectType() - objectId() - rowIds().map { it.validate() } - propagatedEvent().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): SpanParentStruct = apply { + if (validated) { + return@apply } - return other is SpanParentStruct && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.rowIds == other.rowIds && - this.propagatedEvent == other.propagatedEvent && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - rowIds, - propagatedEvent, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + propagatedEvent().ifPresent { it.validate() } + rowIds().ifPresent { it.validate() } + validated = true } - override fun toString() = - "SpanParentStruct{objectType=$objectType, objectId=$objectId, rowIds=$rowIds, propagatedEvent=$propagatedEvent, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [SpanParentStruct]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [SpanParentStruct]. */ + class Builder internal constructor() { - private var objectType: JsonField = JsonMissing.of() - private var objectId: JsonField = JsonMissing.of() - private var rowIds: JsonField = JsonMissing.of() + private var objectId: JsonField? = null + private var objectType: JsonField? = null private var propagatedEvent: JsonField = JsonMissing.of() + private var rowIds: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(spanParentStruct: SpanParentStruct) = apply { - this.objectType = spanParentStruct.objectType - this.objectId = spanParentStruct.objectId - this.rowIds = spanParentStruct.rowIds - this.propagatedEvent = spanParentStruct.propagatedEvent - additionalProperties(spanParentStruct.additionalProperties) - } - - fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) - - @JsonProperty("object_type") - @ExcludeMissing - fun objectType(objectType: JsonField) = apply { - this.objectType = objectType + objectId = spanParentStruct.objectId + objectType = spanParentStruct.objectType + propagatedEvent = spanParentStruct.propagatedEvent + rowIds = spanParentStruct.rowIds + additionalProperties = spanParentStruct.additionalProperties.toMutableMap() } /** The id of the container object you are logging to */ fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - /** The id of the container object you are logging to */ - @JsonProperty("object_id") - @ExcludeMissing + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun objectId(objectId: JsonField) = apply { this.objectId = objectId } - /** Identifiers for the row to to log a subspan under */ - fun rowIds(rowIds: RowIds) = rowIds(JsonField.of(rowIds)) - - /** Identifiers for the row to to log a subspan under */ - @JsonProperty("row_ids") - @ExcludeMissing - fun rowIds(rowIds: JsonField) = apply { this.rowIds = rowIds } + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) - /** Include these properties in every span created under this parent */ - fun propagatedEvent(propagatedEvent: PropagatedEvent) = - propagatedEvent(JsonField.of(propagatedEvent)) + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** Include these properties in every span created under this parent */ - @JsonProperty("propagated_event") - @ExcludeMissing + fun propagatedEvent(propagatedEvent: PropagatedEvent?) = + propagatedEvent(JsonField.ofNullable(propagatedEvent)) + + /** + * Alias for calling [Builder.propagatedEvent] with `propagatedEvent.orElse(null)`. + */ + fun propagatedEvent(propagatedEvent: Optional) = + propagatedEvent(propagatedEvent.getOrNull()) + + /** + * Sets [Builder.propagatedEvent] to an arbitrary JSON value. + * + * You should usually call [Builder.propagatedEvent] with a well-typed + * [PropagatedEvent] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ fun propagatedEvent(propagatedEvent: JsonField) = apply { this.propagatedEvent = propagatedEvent } + /** Identifiers for the row to to log a subspan under */ + fun rowIds(rowIds: RowIds?) = rowIds(JsonField.ofNullable(rowIds)) + + /** Alias for calling [Builder.rowIds] with `rowIds.orElse(null)`. */ + fun rowIds(rowIds: Optional) = rowIds(rowIds.getOrNull()) + + /** + * Sets [Builder.rowIds] to an arbitrary JSON value. + * + * You should usually call [Builder.rowIds] with a well-typed [RowIds] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun rowIds(rowIds: JsonField) = apply { this.rowIds = rowIds } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2518,138 +3943,198 @@ constructor( 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 [SpanParentStruct]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): SpanParentStruct = SpanParentStruct( - objectType, - objectId, - rowIds, + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), propagatedEvent, - additionalProperties.toUnmodifiable(), + rowIds, + additionalProperties.toImmutable(), ) } class ObjectType @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val PROJECT_LOGS = ObjectType(JsonField.of("project_logs")) + @JvmField val PROJECT_LOGS = of("project_logs") + + @JvmField val EXPERIMENT = of("experiment") - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + @JvmField val PLAYGROUND_LOGS = of("playground_logs") @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) } + /** An enum containing [ObjectType]'s known values. */ enum class Known { PROJECT_LOGS, EXPERIMENT, + PLAYGROUND_LOGS, } + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { PROJECT_LOGS, EXPERIMENT, + PLAYGROUND_LOGS, + /** + * An enum member indicating that [ObjectType] 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) { PROJECT_LOGS -> Value.PROJECT_LOGS EXPERIMENT -> Value.EXPERIMENT + PLAYGROUND_LOGS -> Value.PLAYGROUND_LOGS 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { PROJECT_LOGS -> Known.PROJECT_LOGS EXPERIMENT -> Known.EXPERIMENT + PLAYGROUND_LOGS -> Known.PLAYGROUND_LOGS else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } /** Include these properties in every span created under this parent */ - @JsonDeserialize(builder = PropagatedEvent.Builder::class) @NoAutoDetect class PropagatedEvent + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): PropagatedEvent = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): PropagatedEvent = apply { + if (validated) { + return@apply } - return other is PropagatedEvent && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = - "PropagatedEvent{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PropagatedEvent]. + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [PropagatedEvent]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(propagatedEvent: PropagatedEvent) = apply { - additionalProperties(propagatedEvent.additionalProperties) + additionalProperties = propagatedEvent.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2657,141 +4142,206 @@ constructor( 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 [PropagatedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): PropagatedEvent = - PropagatedEvent(additionalProperties.toUnmodifiable()) + PropagatedEvent(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PropagatedEvent && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PropagatedEvent{additionalProperties=$additionalProperties}" } /** Identifiers for the row to to log a subspan under */ - @JsonDeserialize(builder = RowIds.Builder::class) @NoAutoDetect class RowIds + @JsonCreator private constructor( - private val id: JsonField, - private val spanId: JsonField, - private val rootSpanId: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") + @ExcludeMissing + private val id: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The id of the row */ + /** + * The id of the row + * + * @throws BraintrustInvalidDataException 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 span_id of the row */ - fun spanId(): String = spanId.getRequired("span_id") - - /** The root_span_id of the row */ + /** + * The root_span_id of the row + * + * @throws BraintrustInvalidDataException 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 rootSpanId(): String = rootSpanId.getRequired("root_span_id") - /** The id of the row */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * The span_id of the row + * + * @throws BraintrustInvalidDataException 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 spanId(): String = spanId.getRequired("span_id") - /** The span_id of the row */ - @JsonProperty("span_id") @ExcludeMissing fun _spanId() = spanId + /** + * 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 [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("root_span_id") + @ExcludeMissing + fun _rootSpanId(): JsonField = rootSpanId - /** The root_span_id of the row */ - @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId() = rootSpanId + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RowIds = apply { - if (!validated) { - id() - spanId() - rootSpanId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RowIds = apply { + if (validated) { + return@apply } - return other is RowIds && - this.id == other.id && - this.spanId == other.spanId && - this.rootSpanId == other.rootSpanId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - spanId, - rootSpanId, - additionalProperties, - ) - } - return hashCode + id() + rootSpanId() + spanId() + validated = true } - override fun toString() = - "RowIds{id=$id, spanId=$spanId, rootSpanId=$rootSpanId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RowIds]. + * + * The following fields are required: + * ```java + * .id() + * .rootSpanId() + * .spanId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RowIds]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var spanId: JsonField = JsonMissing.of() - private var rootSpanId: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var rootSpanId: JsonField? = null + private var spanId: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(rowIds: RowIds) = apply { - this.id = rowIds.id - this.spanId = rowIds.spanId - this.rootSpanId = rowIds.rootSpanId - additionalProperties(rowIds.additionalProperties) + id = rowIds.id + rootSpanId = rowIds.rootSpanId + spanId = rowIds.spanId + additionalProperties = rowIds.additionalProperties.toMutableMap() } /** The id of the row */ fun id(id: String) = id(JsonField.of(id)) - /** The id of the row */ - @JsonProperty("id") - @ExcludeMissing + /** + * 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 } - /** The span_id of the row */ - fun spanId(spanId: String) = spanId(JsonField.of(spanId)) - - /** The span_id of the row */ - @JsonProperty("span_id") - @ExcludeMissing - fun spanId(spanId: JsonField) = apply { this.spanId = spanId } - /** The root_span_id of the row */ fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) - /** The root_span_id of the row */ - @JsonProperty("root_span_id") - @ExcludeMissing + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + /** The span_id of the row */ + fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2799,15 +4349,84 @@ constructor( 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 [RowIds]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .rootSpanId() + * .spanId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RowIds = RowIds( - id, - spanId, - rootSpanId, - additionalProperties.toUnmodifiable(), + checkRequired("id", id), + checkRequired("rootSpanId", rootSpanId), + checkRequired("spanId", spanId), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RowIds && id == other.id && rootSpanId == other.rootSpanId && spanId == other.spanId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, rootSpanId, spanId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RowIds{id=$id, rootSpanId=$rootSpanId, spanId=$spanId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanParentStruct && objectId == other.objectId && objectType == other.objectType && propagatedEvent == other.propagatedEvent && rowIds == other.rowIds && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, propagatedEvent, rowIds, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SpanParentStruct{objectId=$objectId, objectType=$objectType, propagatedEvent=$propagatedEvent, rowIds=$rowIds, additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is FunctionInvokeParams && functionId == other.functionId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "FunctionInvokeParams{functionId=$functionId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeResponse.kt index 4d510eb4..d7035b68 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionInvokeResponse.kt @@ -5,82 +5,93 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.annotation.JsonCreator import java.util.Objects -@JsonDeserialize(builder = FunctionInvokeResponse.Builder::class) @NoAutoDetect class FunctionInvokeResponse +@JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FunctionInvokeResponse = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionInvokeResponse = apply { + if (validated) { + return@apply } - return other is FunctionInvokeResponse && - this.additionalProperties == other.additionalProperties + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "FunctionInvokeResponse{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [FunctionInvokeResponse]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionInvokeResponse]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionInvokeResponse: FunctionInvokeResponse) = apply { - additionalProperties(functionInvokeResponse.additionalProperties) + additionalProperties = functionInvokeResponse.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FunctionInvokeResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): FunctionInvokeResponse = - FunctionInvokeResponse(additionalProperties.toUnmodifiable()) + FunctionInvokeResponse(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionInvokeResponse && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "FunctionInvokeResponse{additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPage.kt index 9b9e1cac..4f51a5ad 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.FunctionService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all functions. The functions are sorted by creation date, with the most recently-created + * functions coming first + */ class FunctionListPage private constructor( private val functionsService: FunctionService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is FunctionListPage && - this.functionsService == other.functionsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is FunctionListPage && functionsService == other.functionsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - functionsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionsService, params, response) /* spotless:on */ override fun toString() = "FunctionListPage{functionsService=$functionsService, params=$params, response=$response}" @@ -87,23 +84,18 @@ private constructor( @JvmStatic fun of(functionsService: FunctionService, params: FunctionListParams, response: Response) = - FunctionListPage( - functionsService, - params, - response, - ) + FunctionListPage(functionsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -113,11 +105,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -127,20 +123,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "FunctionListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [FunctionListPage]. */ @JvmStatic fun builder() = Builder() } @@ -157,22 +150,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: FunctionListPage, - ) : Iterable { + class AutoPager(private val firstPage: FunctionListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -181,7 +174,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPageAsync.kt index 9daf7ae8..5979e5bf 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.FunctionServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all functions. The functions are sorted by creation date, with the most recently-created + * functions coming first + */ class FunctionListPageAsync private constructor( private val functionsService: FunctionServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is FunctionListPageAsync && - this.functionsService == other.functionsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is FunctionListPageAsync && functionsService == other.functionsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - functionsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionsService, params, response) /* spotless:on */ override fun toString() = "FunctionListPageAsync{functionsService=$functionsService, params=$params, response=$response}" @@ -92,25 +88,19 @@ private constructor( fun of( functionsService: FunctionServiceAsync, params: FunctionListParams, - response: Response - ) = - FunctionListPageAsync( - functionsService, - params, - response, - ) + response: Response, + ) = FunctionListPageAsync(functionsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +110,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +128,19 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "FunctionListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +157,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: FunctionListPageAsync, - ) { + class AutoPager(private val firstPage: FunctionListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Function) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +186,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListParams.kt index 624cd773..534f5284 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all functions. The functions are sorted by creation date, with the most recently-created + * functions coming first + */ class FunctionListParams -constructor( +private constructor( private val endingBefore: String?, private val functionName: String?, private val ids: Ids?, @@ -32,102 +38,106 @@ constructor( private val slug: String?, private val startingAfter: String?, private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** Name of the function to search for */ fun functionName(): Optional = Optional.ofNullable(functionName) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** Retrieve prompt with a specific slug */ fun slug(): Optional = Optional.ofNullable(slug) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) + /** + * Retrieve prompt at a specific version. + * + * The version id can either be a transaction id (e.g. '1000192656880881099') or a version + * identifier (e.g. '81cd05ee665fdfb3'). + */ fun version(): Optional = Optional.ofNullable(version) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.functionName?.let { params.put("function_name", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.slug?.let { params.put("slug", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - this.version?.let { params.put("version", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is FunctionListParams && - this.endingBefore == other.endingBefore && - this.functionName == other.functionName && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.slug == other.slug && - this.startingAfter == other.startingAfter && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - functionName, - ids, - limit, - orgName, - projectId, - projectName, - slug, - startingAfter, - version, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "FunctionListParams{endingBefore=$endingBefore, functionName=$functionName, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, slug=$slug, startingAfter=$startingAfter, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + functionName?.let { put("function_name", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + slug?.let { put("slug", it) } + startingAfter?.let { put("starting_after", it) } + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): FunctionListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [FunctionListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var functionName: String? = null @@ -139,23 +149,23 @@ constructor( private var slug: String? = null private var startingAfter: String? = null private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(functionListParams: FunctionListParams) = apply { - this.endingBefore = functionListParams.endingBefore - this.functionName = functionListParams.functionName - this.ids = functionListParams.ids - this.limit = functionListParams.limit - this.orgName = functionListParams.orgName - this.projectId = functionListParams.projectId - this.projectName = functionListParams.projectName - this.slug = functionListParams.slug - this.startingAfter = functionListParams.startingAfter - this.version = functionListParams.version - additionalQueryParams(functionListParams.additionalQueryParams) - additionalHeaders(functionListParams.additionalHeaders) + endingBefore = functionListParams.endingBefore + functionName = functionListParams.functionName + ids = functionListParams.ids + limit = functionListParams.limit + orgName = functionListParams.orgName + projectId = functionListParams.projectId + projectName = functionListParams.projectName + slug = functionListParams.slug + startingAfter = functionListParams.startingAfter + version = functionListParams.version + additionalHeaders = functionListParams.additionalHeaders.toBuilder() + additionalQueryParams = functionListParams.additionalQueryParams.toBuilder() } /** @@ -165,43 +175,68 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } + + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** Name of the function to search for */ - fun functionName(functionName: String) = apply { this.functionName = functionName } + fun functionName(functionName: String?) = apply { this.functionName = functionName } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.functionName] with `functionName.orElse(null)`. */ + fun functionName(functionName: Optional) = functionName(functionName.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** Retrieve prompt with a specific slug */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String?) = apply { this.slug = slug } + + /** Alias for calling [Builder.slug] with `slug.orElse(null)`. */ + fun slug(slug: Optional) = slug(slug.getOrNull()) /** * Pagination cursor id. @@ -210,7 +245,11 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } + + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) /** * Retrieve prompt at a specific version. @@ -218,48 +257,114 @@ constructor( * The version id can either be a transaction id (e.g. '1000192656880881099') or a version * identifier (e.g. '81cd05ee665fdfb3'). */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { this.version = version } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [FunctionListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): FunctionListParams = FunctionListParams( endingBefore, @@ -272,11 +377,15 @@ constructor( slug, startingAfter, version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -286,8 +395,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -310,35 +417,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -347,21 +442,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -373,12 +479,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -389,4 +495,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionListParams && endingBefore == other.endingBefore && functionName == other.functionName && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && slug == other.slug && startingAfter == other.startingAfter && version == other.version && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, functionName, ids, limit, orgName, projectId, projectName, slug, startingAfter, version, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "FunctionListParams{endingBefore=$endingBefore, functionName=$functionName, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, slug=$slug, startingAfter=$startingAfter, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionReplaceParams.kt index 8612e595..78279e3e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionReplaceParams.kt @@ -10,8 +10,14 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.braintrustdata.api.models.CodeBundle.* import com.fasterxml.jackson.annotation.JsonAnyGetter @@ -27,468 +33,1014 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace function. If there is an existing function in the project with the same slug as + * the one specified in the request, will replace the existing function with the provided fields + */ class FunctionReplaceParams -constructor( - private val functionData: FunctionData, - private val name: String, - private val projectId: String, - private val slug: String, - private val description: String?, - private val functionSchema: FunctionSchema?, - private val functionType: FunctionType?, - private val origin: Origin?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun functionData(): FunctionData = functionData - - fun name(): String = name - - fun projectId(): String = projectId - - fun slug(): String = slug - - fun description(): Optional = Optional.ofNullable(description) - - fun functionSchema(): Optional = Optional.ofNullable(functionSchema) - - fun functionType(): Optional = Optional.ofNullable(functionType) - - fun origin(): Optional = Optional.ofNullable(origin) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): FunctionReplaceBody { - return FunctionReplaceBody( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * @throws BraintrustInvalidDataException 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 functionData(): FunctionData = body.functionData() + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = body.slug() + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * JSON schema for the function's parameters and return type + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionSchema(): Optional = body.functionSchema() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionType(): Optional = body.functionType() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = body.origin() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionData(): JsonField = body._functionData() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _slug(): JsonField = body._slug() + + /** + * 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 [functionSchema]. + * + * Unlike [functionSchema], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionSchema(): JsonField = body._functionSchema() + + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionType(): JsonField = body._functionType() + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _origin(): JsonField = body._origin() + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = FunctionReplaceBody.Builder::class) @NoAutoDetect - class FunctionReplaceBody - internal constructor( - private val functionData: FunctionData?, - private val name: String?, - private val projectId: String?, - private val slug: String?, - private val description: String?, - private val functionSchema: FunctionSchema?, - private val functionType: FunctionType?, - private val origin: Origin?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("function_data") + @ExcludeMissing + private val functionData: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_schema") + @ExcludeMissing + private val functionSchema: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 functionData(): FunctionData = functionData.getRequired("function_data") - @JsonProperty("function_data") fun functionData(): FunctionData? = functionData + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") - /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(): String? = slug + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description + /** + * JSON schema for the function's parameters and return type + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionSchema(): Optional = + Optional.ofNullable(functionSchema.getNullable("function_schema")) - /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") fun functionSchema(): FunctionSchema? = functionSchema + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionType(): Optional = + Optional.ofNullable(functionType.getNullable("function_type")) - @JsonProperty("function_type") fun functionType(): FunctionType? = functionType + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) - @JsonProperty("origin") fun origin(): Origin? = origin + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * Returns the raw JSON value of [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_data") + @ExcludeMissing + fun _functionData(): JsonField = functionData + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * 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 [functionSchema]. + * + * Unlike [functionSchema], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_schema") + @ExcludeMissing + fun _functionSchema(): JsonField = functionSchema + + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is FunctionReplaceBody && - this.functionData == other.functionData && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionSchema == other.functionSchema && - this.functionType == other.functionType && - this.origin == other.origin && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalProperties, - ) - } - return hashCode + functionData().validate() + name() + projectId() + slug() + description() + functionSchema().ifPresent { it.validate() } + functionType() + origin().ifPresent { it.validate() } + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun toString() = - "FunctionReplaceBody{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var functionData: FunctionData? = null - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionSchema: FunctionSchema? = null - private var functionType: FunctionType? = null - private var origin: Origin? = null - private var promptData: PromptData? = null - private var tags: List? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var functionData: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var functionSchema: JsonField = JsonMissing.of() + private var functionType: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(functionReplaceBody: FunctionReplaceBody) = apply { - this.functionData = functionReplaceBody.functionData - this.name = functionReplaceBody.name - this.projectId = functionReplaceBody.projectId - this.slug = functionReplaceBody.slug - this.description = functionReplaceBody.description - this.functionSchema = functionReplaceBody.functionSchema - this.functionType = functionReplaceBody.functionType - this.origin = functionReplaceBody.origin - this.promptData = functionReplaceBody.promptData - this.tags = functionReplaceBody.tags - additionalProperties(functionReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + functionData = body.functionData + name = body.name + projectId = body.projectId + slug = body.slug + description = body.description + functionSchema = body.functionSchema + functionType = body.functionType + origin = body.origin + promptData = body.promptData + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } - @JsonProperty("function_data") - fun functionData(functionData: FunctionData) = apply { + fun functionData(functionData: FunctionData) = functionData(JsonField.of(functionData)) + + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { this.functionData = functionData } + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = + functionData(FunctionData.ofPrompt(prompt)) + + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = functionData(FunctionData.ofCode(code)) + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = + functionData(FunctionData.ofGlobal(global)) + /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = slug(JsonField.of(slug)) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** JSON schema for the function's parameters and return type */ - @JsonProperty("function_schema") - fun functionSchema(functionSchema: FunctionSchema) = apply { + fun functionSchema(functionSchema: FunctionSchema?) = + functionSchema(JsonField.ofNullable(functionSchema)) + + /** Alias for calling [Builder.functionSchema] with `functionSchema.orElse(null)`. */ + fun functionSchema(functionSchema: Optional) = + functionSchema(functionSchema.getOrNull()) + + /** + * Sets [Builder.functionSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.functionSchema] with a well-typed [FunctionSchema] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun functionSchema(functionSchema: JsonField) = apply { this.functionSchema = functionSchema } - @JsonProperty("function_type") - fun functionType(functionType: FunctionType) = apply { + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { this.functionType = functionType } - @JsonProperty("origin") fun origin(origin: Origin) = apply { this.origin = origin } + fun origin(origin: Origin?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionReplaceBody = - FunctionReplaceBody( - checkNotNull(functionData) { "`functionData` is required but was not set" }, - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, + 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 + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("functionData", functionData), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("slug", slug), description, functionSchema, functionType, origin, promptData, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && functionData == other.functionData && name == other.name && projectId == other.projectId && slug == other.slug && description == other.description && functionSchema == other.functionSchema && functionType == other.functionType && origin == other.origin && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is FunctionReplaceParams && - this.functionData == other.functionData && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionSchema == other.functionSchema && - this.functionType == other.functionType && - this.origin == other.origin && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(functionData, name, projectId, slug, description, functionSchema, functionType, origin, promptData, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - functionData, - name, - projectId, - slug, - description, - functionSchema, - functionType, - origin, - promptData, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "FunctionReplaceParams{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{functionData=$functionData, name=$name, projectId=$projectId, slug=$slug, description=$description, functionSchema=$functionSchema, functionType=$functionType, origin=$origin, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionReplaceParams]. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionReplaceParams]. */ @NoAutoDetect - class Builder { - - private var functionData: FunctionData? = null - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionSchema: FunctionSchema? = null - private var functionType: FunctionType? = null - private var origin: Origin? = null - private var promptData: PromptData? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(functionReplaceParams: FunctionReplaceParams) = apply { - this.functionData = functionReplaceParams.functionData - this.name = functionReplaceParams.name - this.projectId = functionReplaceParams.projectId - this.slug = functionReplaceParams.slug - this.description = functionReplaceParams.description - this.functionSchema = functionReplaceParams.functionSchema - this.functionType = functionReplaceParams.functionType - this.origin = functionReplaceParams.origin - this.promptData = functionReplaceParams.promptData - this.tags(functionReplaceParams.tags ?: listOf()) - additionalQueryParams(functionReplaceParams.additionalQueryParams) - additionalHeaders(functionReplaceParams.additionalHeaders) - additionalBodyProperties(functionReplaceParams.additionalBodyProperties) + body = functionReplaceParams.body.toBuilder() + additionalHeaders = functionReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = functionReplaceParams.additionalQueryParams.toBuilder() } - fun functionData(functionData: FunctionData) = apply { this.functionData = functionData } + fun functionData(functionData: FunctionData) = apply { body.functionData(functionData) } - fun functionData(prompt: FunctionData.Prompt) = apply { - this.functionData = FunctionData.ofPrompt(prompt) + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { + body.functionData(functionData) } - fun functionData(code: FunctionData.Code) = apply { - this.functionData = FunctionData.ofCode(code) - } + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = apply { body.functionData(prompt) } - fun functionData(global: FunctionData.Global) = apply { - this.functionData = FunctionData.ofGlobal(global) - } + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = apply { body.functionData(code) } + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = apply { body.functionData(global) } /** Name of the prompt */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Unique identifier for the prompt */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = apply { body.slug(slug) } + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun slug(slug: JsonField) = apply { body.slug(slug) } /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + 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) } /** JSON schema for the function's parameters and return type */ - fun functionSchema(functionSchema: FunctionSchema) = apply { - this.functionSchema = functionSchema + fun functionSchema(functionSchema: FunctionSchema?) = apply { + body.functionSchema(functionSchema) } - fun functionType(functionType: FunctionType) = apply { this.functionType = functionType } + /** Alias for calling [Builder.functionSchema] with `functionSchema.orElse(null)`. */ + fun functionSchema(functionSchema: Optional) = + functionSchema(functionSchema.getOrNull()) - fun origin(origin: Origin) = apply { this.origin = origin } + /** + * Sets [Builder.functionSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.functionSchema] with a well-typed [FunctionSchema] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionSchema(functionSchema: JsonField) = apply { + body.functionSchema(functionSchema) + } - /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun functionType(functionType: FunctionType?) = apply { body.functionType(functionType) } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { + body.functionType(functionType) } + fun origin(origin: Origin?) = apply { body.origin(origin) } + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun origin(origin: JsonField) = apply { body.origin(origin) } + + /** The prompt, model, and its parameters */ + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } + /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun tags(tags: List?) = apply { body.tags(tags) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [FunctionReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionData() + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionReplaceParams = FunctionReplaceParams( - checkNotNull(functionData) { "`functionData` is required but was not set" }, - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, - description, - functionSchema, - functionType, - origin, - promptData, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -502,8 +1054,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun prompt(): Optional = Optional.ofNullable(prompt) fun code(): Optional = Optional.ofNullable(code) @@ -533,16 +1083,29 @@ constructor( } } + private var validated: Boolean = false + fun validate(): FunctionData = apply { - if (!validated) { - if (prompt == null && code == null && global == null) { - throw BraintrustInvalidDataException("Unknown FunctionData: $_json") - } - prompt?.validate() - code?.validate() - global?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitPrompt(prompt: Prompt) { + prompt.validate() + } + + override fun visitCode(code: Code) { + code.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -550,29 +1113,19 @@ constructor( return true } - return other is FunctionData && - this.prompt == other.prompt && - this.code == other.code && - this.global == other.global + return /* spotless:off */ other is FunctionData && prompt == other.prompt && code == other.code && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - prompt, - code, - global, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(prompt, code, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { prompt != null -> "FunctionData{prompt=$prompt}" code != null -> "FunctionData{code=$code}" global != null -> "FunctionData{global=$global}" _json != null -> "FunctionData{_unknown=$_json}" else -> throw IllegalStateException("Invalid FunctionData") } - } companion object { @@ -583,6 +1136,10 @@ constructor( @JvmStatic fun ofGlobal(global: Global) = FunctionData(global = global) } + /** + * An interface that defines how to map each variant of [FunctionData] to a value of type + * [T]. + */ interface Visitor { fun visitPrompt(prompt: Prompt): T @@ -591,15 +1148,26 @@ constructor( fun visitGlobal(global: Global): T + /** + * Maps an unknown variant of [FunctionData] to a value of type [T]. + * + * An instance of [FunctionData] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown FunctionData: $json") } } - class Deserializer : BaseDeserializer(FunctionData::class) { + internal class Deserializer : BaseDeserializer(FunctionData::class) { override fun ObjectCodec.deserialize(node: JsonNode): FunctionData { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return FunctionData(prompt = it, _json = json) @@ -617,12 +1185,12 @@ constructor( } } - class Serializer : BaseSerializer(FunctionData::class) { + internal class Serializer : BaseSerializer(FunctionData::class) { override fun serialize( value: FunctionData, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.prompt != null -> generator.writeObject(value.prompt) @@ -634,85 +1202,91 @@ constructor( } } - @JsonDeserialize(builder = Prompt.Builder::class) @NoAutoDetect class Prompt + @JsonCreator private constructor( - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Prompt = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Prompt = apply { + if (validated) { + return@apply } - return other is Prompt && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode + type() + validated = true } - override fun toString() = - "Prompt{type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Prompt]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Prompt]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(prompt: Prompt) = apply { - this.type = prompt.type - additionalProperties(prompt.additionalProperties) + type = prompt.type + additionalProperties = prompt.additionalProperties.toMutableMap() } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -720,160 +1294,268 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Prompt = Prompt(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - return other is Type && this.value == other.value + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [Prompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Prompt = + Prompt(checkRequired("type", type), additionalProperties.toImmutable()) + } - override fun toString() = value.toString() + class Type @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 PROMPT = Type(JsonField.of("prompt")) + @JvmField val PROMPT = of("prompt") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - PROMPT, + PROMPT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { PROMPT, + /** + * An enum member indicating that [Type] 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) { PROMPT -> Value.PROMPT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { PROMPT -> Known.PROMPT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Prompt && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Prompt{type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Code.Builder::class) @NoAutoDetect class Code + @JsonCreator private constructor( - private val type: JsonField, - private val data: JsonField, - private val additionalProperties: Map, + @JsonProperty("data") + @ExcludeMissing + private val data: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 data(): Data = data.getRequired("data") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun data(): Data = data.getRequired("data") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data - @JsonProperty("data") @ExcludeMissing fun _data() = data + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Code = apply { - if (!validated) { - type() - data() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Code = apply { + if (validated) { + return@apply } - return other is Code && - this.type == other.type && - this.data == other.data && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - data, - additionalProperties, - ) - } - return hashCode + data().validate() + type() + validated = true } - override fun toString() = - "Code{type=$type, data=$data, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Code]. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Code]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var data: JsonField = JsonMissing.of() + private var data: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(code: Code) = apply { - this.type = code.type - this.data = code.data - additionalProperties(code.additionalProperties) + data = code.data + type = code.type + additionalProperties = code.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun data(data: Data) = data(JsonField.of(data)) - @JsonProperty("data") - @ExcludeMissing + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun data(data: JsonField) = apply { this.data = data } + /** Alias for calling [data] with `Data.ofBundle(bundle)`. */ + fun data(bundle: Data.Bundle) = data(Data.ofBundle(bundle)) + + /** Alias for calling [data] with `Data.ofInline(inline)`. */ + fun data(inline: Data.Inline) = data(Data.ofInline(inline)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -881,11 +1563,32 @@ constructor( 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 [Code]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Code = Code( - type, - data, - additionalProperties.toUnmodifiable(), + checkRequired("data", data), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } @@ -898,8 +1601,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun bundle(): Optional = Optional.ofNullable(bundle) fun inline(): Optional = Optional.ofNullable(inline) @@ -922,14 +1623,25 @@ constructor( } } + private var validated: Boolean = false + fun validate(): Data = apply { - if (!validated) { - if (bundle == null && inline == null) { - throw BraintrustInvalidDataException("Unknown Data: $_json") - } - inline?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitBundle(bundle: Bundle) { + bundle.validate() + } + + override fun visitInline(inline: Inline) { + inline.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -937,23 +1649,18 @@ constructor( return true } - return other is Data && - this.bundle == other.bundle && - this.inline == other.inline + return /* spotless:off */ other is Data && bundle == other.bundle && inline == other.inline /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(bundle, inline) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(bundle, inline) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { bundle != null -> "Data{bundle=$bundle}" inline != null -> "Data{inline=$inline}" _json != null -> "Data{_unknown=$_json}" else -> throw IllegalStateException("Invalid Data") } - } companion object { @@ -962,24 +1669,40 @@ constructor( @JvmStatic fun ofInline(inline: Inline) = Data(inline = inline) } + /** + * An interface that defines how to map each variant of [Data] to a value of type + * [T]. + */ interface Visitor { fun visitBundle(bundle: Bundle): T fun visitInline(inline: Inline): T + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Data: $json") } } - class Deserializer : BaseDeserializer(Data::class) { + internal class Deserializer : BaseDeserializer(Data::class) { override fun ObjectCodec.deserialize(node: JsonNode): Data { val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return Data(bundle = it, _json = json) - } + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(bundle = it, _json = json) + } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Data(inline = it, _json = json) @@ -989,12 +1712,12 @@ constructor( } } - class Serializer : BaseSerializer(Data::class) { + internal class Serializer : BaseSerializer(Data::class) { override fun serialize( value: Data, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.bundle != null -> generator.writeObject(value.bundle) @@ -1005,478 +1728,748 @@ constructor( } } - @JsonDeserialize(builder = Bundle.Builder::class) @NoAutoDetect class Bundle + @JsonCreator private constructor( - private val runtimeContext: JsonField, - private val location: JsonField, - private val bundleId: JsonField, - private val preview: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("bundle_id") + @ExcludeMissing + private val bundleId: JsonField = JsonMissing.of(), + @JsonProperty("location") + @ExcludeMissing + private val location: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = + JsonMissing.of(), + @JsonProperty("preview") + @ExcludeMissing + private val preview: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 bundleId(): String = bundleId.getRequired("bundle_id") - fun runtimeContext(): RuntimeContext = + /** + * @throws BraintrustInvalidDataException 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 location(): CodeBundle.Location = location.getRequired("location") + + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): CodeBundle.RuntimeContext = runtimeContext.getRequired("runtime_context") - fun location(): Location = location.getRequired("location") - - fun bundleId(): String = bundleId.getRequired("bundle_id") - - /** A preview of the code */ + /** + * A preview of the code + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun preview(): Optional = Optional.ofNullable(preview.getNullable("preview")) + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun toCodeBundle(): CodeBundle = - CodeBundle.builder() - .runtimeContext(runtimeContext) - .location(location) - .bundleId(bundleId) - .preview(preview) - .build() - + /** + * Returns the raw JSON value of [bundleId]. + * + * Unlike [bundleId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("bundle_id") + @ExcludeMissing + fun _bundleId(): JsonField = bundleId + + /** + * Returns the raw JSON value of [location]. + * + * Unlike [location], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("location") + @ExcludeMissing + fun _location(): JsonField = location + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext - - @JsonProperty("location") @ExcludeMissing fun _location() = location - - @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId() = bundleId - - /** A preview of the code */ - @JsonProperty("preview") @ExcludeMissing fun _preview() = preview + fun _runtimeContext(): JsonField = runtimeContext + + /** + * Returns the raw JSON value of [preview]. + * + * Unlike [preview], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("preview") + @ExcludeMissing + fun _preview(): JsonField = preview - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Bundle = apply { - if (!validated) { - runtimeContext().validate() - location() - bundleId() - preview() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun toCodeBundle(): CodeBundle = + CodeBundle.builder() + .bundleId(bundleId) + .location(location) + .runtimeContext(runtimeContext) + .preview(preview) + .build() - return other is Bundle && - this.runtimeContext == other.runtimeContext && - this.location == other.location && - this.bundleId == other.bundleId && - this.preview == other.preview && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtimeContext, - location, - bundleId, - preview, - type, - additionalProperties, - ) + fun validate(): Bundle = apply { + if (validated) { + return@apply } - return hashCode + + bundleId() + location().validate() + runtimeContext().validate() + preview() + type() + validated = true } - override fun toString() = - "Bundle{runtimeContext=$runtimeContext, location=$location, bundleId=$bundleId, preview=$preview, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Bundle]. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Bundle]. */ + class Builder internal constructor() { - private var runtimeContext: JsonField = JsonMissing.of() - private var location: JsonField = JsonMissing.of() - private var bundleId: JsonField = JsonMissing.of() + private var bundleId: JsonField? = null + private var location: JsonField? = null + private var runtimeContext: JsonField? = null private var preview: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(bundle: Bundle) = apply { - this.runtimeContext = bundle.runtimeContext - this.location = bundle.location - this.bundleId = bundle.bundleId - this.preview = bundle.preview - this.type = bundle.type - additionalProperties(bundle.additionalProperties) + bundleId = bundle.bundleId + location = bundle.location + runtimeContext = bundle.runtimeContext + preview = bundle.preview + type = bundle.type + additionalProperties = bundle.additionalProperties.toMutableMap() } - fun runtimeContext(runtimeContext: RuntimeContext) = - runtimeContext(JsonField.of(runtimeContext)) + fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - @JsonProperty("runtime_context") - @ExcludeMissing - fun runtimeContext(runtimeContext: JsonField) = apply { - this.runtimeContext = runtimeContext + /** + * Sets [Builder.bundleId] to an arbitrary JSON value. + * + * You should usually call [Builder.bundleId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun bundleId(bundleId: JsonField) = apply { + this.bundleId = bundleId } - fun location(location: Location) = location(JsonField.of(location)) - - @JsonProperty("location") - @ExcludeMissing - fun location(location: JsonField) = apply { + fun location(location: CodeBundle.Location) = + location(JsonField.of(location)) + + /** + * Sets [Builder.location] to an arbitrary JSON value. + * + * You should usually call [Builder.location] with a well-typed + * [CodeBundle.Location] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun location(location: JsonField) = apply { this.location = location } - fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - - @JsonProperty("bundle_id") - @ExcludeMissing - fun bundleId(bundleId: JsonField) = apply { - this.bundleId = bundleId - } + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofExperiment(experiment)`. + */ + fun location(experiment: CodeBundle.Location.Experiment) = + location(CodeBundle.Location.ofExperiment(experiment)) + + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofFunction(function)`. + */ + fun location(function: CodeBundle.Location.Function) = + location(CodeBundle.Location.ofFunction(function)) + + fun runtimeContext(runtimeContext: CodeBundle.RuntimeContext) = + runtimeContext(JsonField.of(runtimeContext)) - /** A preview of the code */ - fun preview(preview: String) = preview(JsonField.of(preview)) + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [CodeBundle.RuntimeContext] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun runtimeContext(runtimeContext: JsonField) = + apply { + this.runtimeContext = runtimeContext + } /** A preview of the code */ - @JsonProperty("preview") - @ExcludeMissing + fun preview(preview: String?) = preview(JsonField.ofNullable(preview)) + + /** Alias for calling [Builder.preview] with `preview.orElse(null)`. */ + fun preview(preview: Optional) = preview(preview.getOrNull()) + + /** + * Sets [Builder.preview] to an arbitrary JSON value. + * + * You should usually call [Builder.preview] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun preview(preview: JsonField) = apply { this.preview = preview } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Bundle]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Bundle = Bundle( - runtimeContext, - location, - bundleId, + checkRequired("bundleId", bundleId), + checkRequired("location", location), + checkRequired("runtimeContext", runtimeContext), preview, - type, - additionalProperties.toUnmodifiable(), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } class Type @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val BUNDLE = Type(JsonField.of("bundle")) + @JvmField val BUNDLE = of("bundle") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - BUNDLE, + BUNDLE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { BUNDLE, + /** + * An enum member indicating that [Type] 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) { BUNDLE -> Value.BUNDLE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { BUNDLE -> Known.BUNDLE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Bundle && bundleId == other.bundleId && location == other.location && runtimeContext == other.runtimeContext && preview == other.preview && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(bundleId, location, runtimeContext, preview, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Bundle{bundleId=$bundleId, location=$location, runtimeContext=$runtimeContext, preview=$preview, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Inline.Builder::class) @NoAutoDetect class Inline + @JsonCreator private constructor( - private val type: JsonField, - private val runtimeContext: JsonField, - private val code: JsonField, - private val additionalProperties: Map, + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") - fun code(): String = code.getRequired("code") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext + fun _runtimeContext(): JsonField = runtimeContext - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Inline = apply { - if (!validated) { - type() - runtimeContext().validate() - code() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Inline = apply { + if (validated) { + return@apply } - return other is Inline && - this.type == other.type && - this.runtimeContext == other.runtimeContext && - this.code == other.code && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - runtimeContext, - code, - additionalProperties, - ) - } - return hashCode + code() + runtimeContext().validate() + type() + validated = true } - override fun toString() = - "Inline{type=$type, runtimeContext=$runtimeContext, code=$code, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Inline]. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Inline]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var runtimeContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() + private var code: JsonField? = null + private var runtimeContext: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inline: Inline) = apply { - this.type = inline.type - this.runtimeContext = inline.runtimeContext - this.code = inline.code - additionalProperties(inline.additionalProperties) + code = inline.code + runtimeContext = inline.runtimeContext + type = inline.type + additionalProperties = inline.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) + fun code(code: String) = code(JsonField.of(code)) - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } fun runtimeContext(runtimeContext: RuntimeContext) = runtimeContext(JsonField.of(runtimeContext)) - @JsonProperty("runtime_context") - @ExcludeMissing + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [RuntimeContext] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun runtimeContext(runtimeContext: JsonField) = apply { this.runtimeContext = runtimeContext } - fun code(code: String) = code(JsonField.of(code)) + fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Inline]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Inline = Inline( - type, - runtimeContext, - code, - additionalProperties.toUnmodifiable(), + checkRequired("code", code), + checkRequired("runtimeContext", runtimeContext), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = RuntimeContext.Builder::class) @NoAutoDetect class RuntimeContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime - - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("version") + @ExcludeMissing + fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RuntimeContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RuntimeContext = apply { + if (validated) { + return@apply } - return other is RuntimeContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [RuntimeContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RuntimeContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(runtimeContext: RuntimeContext) = apply { - this.runtime = runtimeContext.runtime - this.version = runtimeContext.version - additionalProperties(runtimeContext.additionalProperties) + runtime = runtimeContext.runtime + version = runtimeContext.version + additionalProperties = + runtimeContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } @@ -1484,67 +2477,106 @@ constructor( fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RuntimeContext]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RuntimeContext = RuntimeContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } class Runtime @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -1552,6 +2584,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value + * is a not a known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -1562,215 +2603,403 @@ constructor( ) } - fun asString(): String = _value().asStringOrThrow() - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is RuntimeContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + class Type + @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 INLINE = Type(JsonField.of("inline")) + @JvmField val INLINE = of("inline") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - INLINE, + INLINE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { INLINE, + /** + * An enum member indicating that [Type] 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) { INLINE -> Value.INLINE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { INLINE -> Known.INLINE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - return other is Type && this.value == other.value - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun hashCode() = value.hashCode() + return /* spotless:off */ other is Inline && code == other.code && runtimeContext == other.runtimeContext && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - override fun toString() = value.toString() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, runtimeContext, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Inline{code=$code, runtimeContext=$runtimeContext, type=$type, additionalProperties=$additionalProperties}" + } + } + + class Type @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 CODE = Type(JsonField.of("code")) + @JvmField val CODE = of("code") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - CODE, + CODE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { CODE, + /** + * An enum member indicating that [Type] was instantiated with an unknown value. + */ _UNKNOWN, } - fun value(): Value = - when (this) { - CODE -> Value.CODE - else -> 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) { + CODE -> Value.CODE + 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + CODE -> Known.CODE + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Code && data == other.data && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun known(): Known = - when (this) { - CODE -> Known.CODE - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, type, additionalProperties) } + /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun hashCode(): Int = hashCode + + override fun toString() = + "Code{data=$data, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1778,195 +3007,281 @@ constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" } } /** JSON schema for the function's parameters and return type */ - @JsonDeserialize(builder = FunctionSchema.Builder::class) @NoAutoDetect class FunctionSchema + @JsonCreator private constructor( - private val parameters: JsonValue?, - private val returns: JsonValue?, - private val additionalProperties: Map, + @JsonProperty("parameters") + @ExcludeMissing + private val parameters: JsonValue = JsonMissing.of(), + @JsonProperty("returns") @ExcludeMissing private val returns: JsonValue = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + @JsonProperty("parameters") @ExcludeMissing fun _parameters(): JsonValue = parameters - @JsonProperty("parameters") fun parameters(): JsonValue? = parameters - - @JsonProperty("returns") fun returns(): JsonValue? = returns + @JsonProperty("returns") @ExcludeMissing fun _returns(): JsonValue = returns @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionSchema = apply { + if (validated) { + return@apply } - return other is FunctionSchema && - this.parameters == other.parameters && - this.returns == other.returns && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - parameters, - returns, - additionalProperties, - ) - } - return hashCode + validated = true } - override fun toString() = - "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [FunctionSchema]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionSchema]. */ + class Builder internal constructor() { - private var parameters: JsonValue? = null - private var returns: JsonValue? = null + private var parameters: JsonValue = JsonMissing.of() + private var returns: JsonValue = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionSchema: FunctionSchema) = apply { - this.parameters = functionSchema.parameters - this.returns = functionSchema.returns - additionalProperties(functionSchema.additionalProperties) + parameters = functionSchema.parameters + returns = functionSchema.returns + additionalProperties = functionSchema.additionalProperties.toMutableMap() } - @JsonProperty("parameters") fun parameters(parameters: JsonValue) = apply { this.parameters = parameters } - @JsonProperty("returns") fun returns(returns: JsonValue) = apply { this.returns = returns } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionSchema = - FunctionSchema( - parameters, - returns, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [FunctionSchema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FunctionSchema = + FunctionSchema(parameters, returns, additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is FunctionType && this.value == other.value + return /* spotless:off */ other is FunctionSchema && parameters == other.parameters && returns == other.returns && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(parameters, returns, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionSchema{parameters=$parameters, returns=$returns, additionalProperties=$additionalProperties}" + } + + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -1974,14 +3289,33 @@ constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -1991,6 +3325,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -2000,234 +3343,267 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - @JsonDeserialize(builder = Origin.Builder::class) @NoAutoDetect class Origin + @JsonCreator private constructor( - private val objectType: ObjectType?, - private val objectId: String?, - private val internal_: Boolean?, - private val additionalProperties: Map, + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("internal") + @ExcludeMissing + private val internal_: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * Id of the object the function is originating from + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** Id of the object the function is originating from */ - @JsonProperty("object_id") fun objectId(): String? = objectId + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") /** * The function exists for internal purposes and should not be displayed in the list of * functions. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun internal_(): Optional = Optional.ofNullable(internal_.getNullable("internal")) + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [internal_]. + * + * Unlike [internal_], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("internal") fun internal_(): Boolean? = internal_ + @JsonProperty("internal") @ExcludeMissing fun _internal_(): JsonField = internal_ @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Origin = apply { + if (validated) { + return@apply } - return other is Origin && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.internal_ == other.internal_ && - this.additionalProperties == other.additionalProperties + objectId() + objectType() + internal_() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectType, - objectId, - internal_, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Origin{objectType=$objectType, objectId=$objectId, internal_=$internal_, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Origin]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Origin]. */ + class Builder internal constructor() { - private var objectType: ObjectType? = null - private var objectId: String? = null - private var internal_: Boolean? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var internal_: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(origin: Origin) = apply { - this.objectType = origin.objectType - this.objectId = origin.objectId - this.internal_ = origin.internal_ - additionalProperties(origin.additionalProperties) + objectId = origin.objectId + objectType = origin.objectType + internal_ = origin.internal_ + additionalProperties = origin.additionalProperties.toMutableMap() } + /** Id of the object the function is originating from */ + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) - /** Id of the object the function is originating from */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** * The function exists for internal purposes and should not be displayed in the list of * functions. */ - @JsonProperty("internal") - fun internal_(internal_: Boolean) = apply { this.internal_ = internal_ } + fun internal_(internal_: Boolean?) = internal_(JsonField.ofNullable(internal_)) + + /** + * Alias for [Builder.internal_]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun internal_(internal_: Boolean) = internal_(internal_ as Boolean?) + + /** Alias for calling [Builder.internal_] with `internal_.orElse(null)`. */ + fun internal_(internal_: Optional) = internal_(internal_.getOrNull()) + + /** + * Sets [Builder.internal_] to an arbitrary JSON value. + * + * You should usually call [Builder.internal_] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun internal_(internal_: JsonField) = apply { this.internal_ = internal_ } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Origin]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Origin = Origin( - checkNotNull(objectType) { "`objectType` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), internal_, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = ObjectType(JsonField.of("group")) - - @JvmField val ROLE = ObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + return /* spotless:off */ other is Origin && objectId == other.objectId && objectType == other.objectType && internal_ == other.internal_ && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, internal_, additionalProperties) } + /* spotless:on */ - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) - } + override fun hashCode(): Int = hashCode - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + override fun toString() = + "Origin{objectId=$objectId, objectType=$objectType, internal_=$internal_, additionalProperties=$additionalProperties}" + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is FunctionReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "FunctionReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionRetrieveParams.kt index 815fc34d..e76a50f4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a function object by its id */ class FunctionRetrieveParams -constructor( +private constructor( private val functionId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Function id */ fun functionId(): String = functionId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is FunctionRetrieveParams && - this.functionId == other.functionId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - functionId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "FunctionRetrieveParams{functionId=$functionId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionRetrieveParams]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var functionId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(functionRetrieveParams: FunctionRetrieveParams) = apply { - this.functionId = functionRetrieveParams.functionId - additionalQueryParams(functionRetrieveParams.additionalQueryParams) - additionalHeaders(functionRetrieveParams.additionalHeaders) + functionId = functionRetrieveParams.functionId + additionalHeaders = functionRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = functionRetrieveParams.additionalQueryParams.toBuilder() } /** Function id */ fun functionId(functionId: String) = apply { this.functionId = functionId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [FunctionRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionRetrieveParams = FunctionRetrieveParams( - checkNotNull(functionId) { "`functionId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("functionId", functionId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionRetrieveParams && functionId == other.functionId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "FunctionRetrieveParams{functionId=$functionId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionToolChoice.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionToolChoice.kt deleted file mode 100644 index 78763bef..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionToolChoice.kt +++ /dev/null @@ -1,105 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.util.Objects - -@JsonDeserialize(builder = FunctionToolChoice.Builder::class) -@NoAutoDetect -class FunctionToolChoice -private constructor( - private val name: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun name(): String = name.getRequired("name") - - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): FunctionToolChoice = apply { - if (!validated) { - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is FunctionToolChoice && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(name, additionalProperties) - } - return hashCode - } - - override fun toString() = - "FunctionToolChoice{name=$name, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(functionToolChoice: FunctionToolChoice) = apply { - this.name = functionToolChoice.name - additionalProperties(functionToolChoice.additionalProperties) - } - - fun name(name: String) = name(JsonField.of(name)) - - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): FunctionToolChoice = - FunctionToolChoice(name, additionalProperties.toUnmodifiable()) - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionUpdateParams.kt index 0c7e7c41..be7afe1f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/FunctionUpdateParams.kt @@ -10,8 +10,14 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.braintrustdata.api.models.CodeBundle.* import com.fasterxml.jackson.annotation.JsonAnyGetter @@ -27,47 +33,108 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a function object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class FunctionUpdateParams -constructor( +private constructor( private val functionId: String, - private val description: String?, - private val functionData: FunctionData?, - private val name: String?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Function id */ fun functionId(): String = functionId - fun description(): Optional = Optional.ofNullable(description) - - fun functionData(): Optional = Optional.ofNullable(functionData) - - fun name(): Optional = Optional.ofNullable(name) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): FunctionUpdateBody { - return FunctionUpdateBody( - description, - functionData, - name, - promptData, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionData(): Optional = body.functionData() + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [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 [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionData(): JsonField = body._functionData() + + /** + * 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 [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -76,318 +143,579 @@ constructor( } } - @JsonDeserialize(builder = FunctionUpdateBody.Builder::class) @NoAutoDetect - class FunctionUpdateBody - internal constructor( - private val description: String?, - private val functionData: FunctionData?, - private val name: String?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_data") + @ExcludeMissing + private val functionData: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description - - @JsonProperty("function_data") fun functionData(): FunctionData? = functionData - - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name - - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionData(): Optional = + Optional.ofNullable(functionData.getNullable("function_data")) + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + + /** + * 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 [functionData]. + * + * Unlike [functionData], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_data") + @ExcludeMissing + fun _functionData(): JsonField = functionData + + /** + * 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 [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is FunctionUpdateBody && - this.description == other.description && - this.functionData == other.functionData && - this.name == other.name && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - description, - functionData, - name, - promptData, - tags, - additionalProperties, - ) - } - return hashCode + description() + functionData().ifPresent { it.validate() } + name() + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun toString() = - "FunctionUpdateBody{description=$description, functionData=$functionData, name=$name, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var description: String? = null - private var functionData: FunctionData? = null - private var name: String? = null - private var promptData: PromptData? = null - private var tags: List? = null + private var description: JsonField = JsonMissing.of() + private var functionData: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(functionUpdateBody: FunctionUpdateBody) = apply { - this.description = functionUpdateBody.description - this.functionData = functionUpdateBody.functionData - this.name = functionUpdateBody.name - this.promptData = functionUpdateBody.promptData - this.tags = functionUpdateBody.tags - additionalProperties(functionUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + description = body.description + functionData = body.functionData + name = body.name + promptData = body.promptData + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } - @JsonProperty("function_data") - fun functionData(functionData: FunctionData) = apply { + fun functionData(functionData: FunctionData?) = + functionData(JsonField.ofNullable(functionData)) + + /** Alias for calling [Builder.functionData] with `functionData.orElse(null)`. */ + fun functionData(functionData: Optional) = + functionData(functionData.getOrNull()) + + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { this.functionData = functionData } + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = + functionData(FunctionData.ofPrompt(prompt)) + + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = functionData(FunctionData.ofCode(code)) + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = + functionData(FunctionData.ofGlobal(global)) + /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): FunctionUpdateBody = - FunctionUpdateBody( + 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. + */ + fun build(): Body = + Body( description, functionData, name, promptData, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && description == other.description && functionData == other.functionData && name == other.name && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is FunctionUpdateParams && - this.functionId == other.functionId && - this.description == other.description && - this.functionData == other.functionData && - this.name == other.name && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(description, functionData, name, promptData, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - functionId, - description, - functionData, - name, - promptData, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "FunctionUpdateParams{functionId=$functionId, description=$description, functionData=$functionData, name=$name, promptData=$promptData, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{description=$description, functionData=$functionData, name=$name, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [FunctionUpdateParams]. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [FunctionUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var functionId: String? = null - private var description: String? = null - private var functionData: FunctionData? = null - private var name: String? = null - private var promptData: PromptData? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(functionUpdateParams: FunctionUpdateParams) = apply { - this.functionId = functionUpdateParams.functionId - this.description = functionUpdateParams.description - this.functionData = functionUpdateParams.functionData - this.name = functionUpdateParams.name - this.promptData = functionUpdateParams.promptData - this.tags(functionUpdateParams.tags ?: listOf()) - additionalQueryParams(functionUpdateParams.additionalQueryParams) - additionalHeaders(functionUpdateParams.additionalHeaders) - additionalBodyProperties(functionUpdateParams.additionalBodyProperties) + functionId = functionUpdateParams.functionId + body = functionUpdateParams.body.toBuilder() + additionalHeaders = functionUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = functionUpdateParams.additionalQueryParams.toBuilder() } /** Function id */ fun functionId(functionId: String) = apply { this.functionId = functionId } /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + 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) } + + fun functionData(functionData: FunctionData?) = apply { body.functionData(functionData) } + + /** Alias for calling [Builder.functionData] with `functionData.orElse(null)`. */ + fun functionData(functionData: Optional) = + functionData(functionData.getOrNull()) + + /** + * Sets [Builder.functionData] to an arbitrary JSON value. + * + * You should usually call [Builder.functionData] with a well-typed [FunctionData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionData(functionData: JsonField) = apply { + body.functionData(functionData) + } + + /** Alias for calling [functionData] with `FunctionData.ofPrompt(prompt)`. */ + fun functionData(prompt: FunctionData.Prompt) = apply { body.functionData(prompt) } + + /** Alias for calling [functionData] with `FunctionData.ofCode(code)`. */ + fun functionData(code: FunctionData.Code) = apply { body.functionData(code) } + + /** Alias for calling [functionData] with `FunctionData.ofGlobal(global)`. */ + fun functionData(global: FunctionData.Global) = apply { body.functionData(global) } + + /** Name of the prompt */ + fun name(name: String?) = apply { body.name(name) } - fun functionData(functionData: FunctionData) = apply { this.functionData = functionData } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) - fun functionData(prompt: FunctionData.Prompt) = apply { - this.functionData = FunctionData.ofPrompt(prompt) + /** + * 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) } + + /** The prompt, model, and its parameters */ + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } + + /** A list of tags for the prompt */ + fun tags(tags: List?) = apply { body.tags(tags) } + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 functionData(code: FunctionData.Code) = apply { - this.functionData = FunctionData.ofCode(code) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun functionData(global: FunctionData.Global) = apply { - this.functionData = FunctionData.ofGlobal(global) + 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 functionData(nullableVariant: FunctionData.NullableVariant) = apply { - this.functionData = FunctionData.ofNullableVariant(nullableVariant) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - /** Name of the prompt */ - fun name(name: String) = apply { this.name = name } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [FunctionUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .functionId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionUpdateParams = FunctionUpdateParams( - checkNotNull(functionId) { "`functionId` is required but was not set" }, - description, - functionData, - name, - promptData, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("functionId", functionId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } @@ -398,36 +726,27 @@ constructor( private val prompt: Prompt? = null, private val code: Code? = null, private val global: Global? = null, - private val nullableVariant: NullableVariant? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun prompt(): Optional = Optional.ofNullable(prompt) fun code(): Optional = Optional.ofNullable(code) fun global(): Optional = Optional.ofNullable(global) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) - fun isPrompt(): Boolean = prompt != null fun isCode(): Boolean = code != null fun isGlobal(): Boolean = global != null - fun isNullableVariant(): Boolean = nullableVariant != null - fun asPrompt(): Prompt = prompt.getOrThrow("prompt") fun asCode(): Code = code.getOrThrow("code") fun asGlobal(): Global = global.getOrThrow("global") - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") - fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { @@ -435,22 +754,33 @@ constructor( prompt != null -> visitor.visitPrompt(prompt) code != null -> visitor.visitCode(code) global != null -> visitor.visitGlobal(global) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): FunctionData = apply { - if (!validated) { - if (prompt == null && code == null && global == null && nullableVariant == null) { - throw BraintrustInvalidDataException("Unknown FunctionData: $_json") - } - prompt?.validate() - code?.validate() - global?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitPrompt(prompt: Prompt) { + prompt.validate() + } + + override fun visitCode(code: Code) { + code.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -458,32 +788,19 @@ constructor( return true } - return other is FunctionData && - this.prompt == other.prompt && - this.code == other.code && - this.global == other.global && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is FunctionData && prompt == other.prompt && code == other.code && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - prompt, - code, - global, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(prompt, code, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { prompt != null -> "FunctionData{prompt=$prompt}" code != null -> "FunctionData{code=$code}" global != null -> "FunctionData{global=$global}" - nullableVariant != null -> "FunctionData{nullableVariant=$nullableVariant}" _json != null -> "FunctionData{_unknown=$_json}" else -> throw IllegalStateException("Invalid FunctionData") } - } companion object { @@ -492,12 +809,12 @@ constructor( @JvmStatic fun ofCode(code: Code) = FunctionData(code = code) @JvmStatic fun ofGlobal(global: Global) = FunctionData(global = global) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - FunctionData(nullableVariant = nullableVariant) } + /** + * An interface that defines how to map each variant of [FunctionData] to a value of type + * [T]. + */ interface Visitor { fun visitPrompt(prompt: Prompt): T @@ -506,17 +823,26 @@ constructor( fun visitGlobal(global: Global): T - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** + * Maps an unknown variant of [FunctionData] to a value of type [T]. + * + * An instance of [FunctionData] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown FunctionData: $json") } } - class Deserializer : BaseDeserializer(FunctionData::class) { + internal class Deserializer : BaseDeserializer(FunctionData::class) { override fun ObjectCodec.deserialize(node: JsonNode): FunctionData { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return FunctionData(prompt = it, _json = json) @@ -529,112 +855,113 @@ constructor( ?.let { return FunctionData(global = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return FunctionData(nullableVariant = it, _json = json) - } return FunctionData(_json = json) } } - class Serializer : BaseSerializer(FunctionData::class) { + internal class Serializer : BaseSerializer(FunctionData::class) { override fun serialize( value: FunctionData, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.prompt != null -> generator.writeObject(value.prompt) value.code != null -> generator.writeObject(value.code) value.global != null -> generator.writeObject(value.global) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid FunctionData") } } } - @JsonDeserialize(builder = Prompt.Builder::class) @NoAutoDetect class Prompt + @JsonCreator private constructor( - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Prompt = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Prompt = apply { + if (validated) { + return@apply } - return other is Prompt && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode + type() + validated = true } - override fun toString() = - "Prompt{type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Prompt]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Prompt]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(prompt: Prompt) = apply { - this.type = prompt.type - additionalProperties(prompt.additionalProperties) + type = prompt.type + additionalProperties = prompt.additionalProperties.toMutableMap() } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -642,160 +969,268 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Prompt = Prompt(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - return other is Type && this.value == other.value + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [Prompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Prompt = + Prompt(checkRequired("type", type), additionalProperties.toImmutable()) + } - override fun toString() = value.toString() + class Type @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 PROMPT = Type(JsonField.of("prompt")) + @JvmField val PROMPT = of("prompt") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - PROMPT, + PROMPT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { PROMPT, + /** + * An enum member indicating that [Type] 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) { PROMPT -> Value.PROMPT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { PROMPT -> Known.PROMPT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Prompt && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Prompt{type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Code.Builder::class) @NoAutoDetect class Code + @JsonCreator private constructor( - private val type: JsonField, - private val data: JsonField, - private val additionalProperties: Map, + @JsonProperty("data") + @ExcludeMissing + private val data: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 data(): Data = data.getRequired("data") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun data(): Data = data.getRequired("data") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data - @JsonProperty("data") @ExcludeMissing fun _data() = data + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Code = apply { - if (!validated) { - type() - data() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Code = apply { + if (validated) { + return@apply } - return other is Code && - this.type == other.type && - this.data == other.data && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - data, - additionalProperties, - ) - } - return hashCode + data().validate() + type() + validated = true } - override fun toString() = - "Code{type=$type, data=$data, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Code]. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Code]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var data: JsonField = JsonMissing.of() + private var data: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(code: Code) = apply { - this.type = code.type - this.data = code.data - additionalProperties(code.additionalProperties) + data = code.data + type = code.type + additionalProperties = code.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun data(data: Data) = data(JsonField.of(data)) - @JsonProperty("data") - @ExcludeMissing + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun data(data: JsonField) = apply { this.data = data } + /** Alias for calling [data] with `Data.ofBundle(bundle)`. */ + fun data(bundle: Data.Bundle) = data(Data.ofBundle(bundle)) + + /** Alias for calling [data] with `Data.ofInline(inline)`. */ + fun data(inline: Data.Inline) = data(Data.ofInline(inline)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -803,11 +1238,32 @@ constructor( 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 [Code]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Code = Code( - type, - data, - additionalProperties.toUnmodifiable(), + checkRequired("data", data), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } @@ -820,8 +1276,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun bundle(): Optional = Optional.ofNullable(bundle) fun inline(): Optional = Optional.ofNullable(inline) @@ -844,38 +1298,44 @@ constructor( } } + private var validated: Boolean = false + fun validate(): Data = apply { - if (!validated) { - if (bundle == null && inline == null) { - throw BraintrustInvalidDataException("Unknown Data: $_json") - } - inline?.validate() - validated = true + if (validated) { + return@apply } - } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + accept( + object : Visitor { + override fun visitBundle(bundle: Bundle) { + bundle.validate() + } - return other is Data && - this.bundle == other.bundle && - this.inline == other.inline + override fun visitInline(inline: Inline) { + inline.validate() + } + } + ) + validated = true } - override fun hashCode(): Int { - return Objects.hash(bundle, inline) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Data && bundle == other.bundle && inline == other.inline /* spotless:on */ } - override fun toString(): String { - return when { + override fun hashCode(): Int = /* spotless:off */ Objects.hash(bundle, inline) /* spotless:on */ + + override fun toString(): String = + when { bundle != null -> "Data{bundle=$bundle}" inline != null -> "Data{inline=$inline}" _json != null -> "Data{_unknown=$_json}" else -> throw IllegalStateException("Invalid Data") } - } companion object { @@ -884,24 +1344,40 @@ constructor( @JvmStatic fun ofInline(inline: Inline) = Data(inline = inline) } + /** + * An interface that defines how to map each variant of [Data] to a value of type + * [T]. + */ interface Visitor { fun visitBundle(bundle: Bundle): T fun visitInline(inline: Inline): T + /** + * Maps an unknown variant of [Data] to a value of type [T]. + * + * An instance of [Data] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Data: $json") } } - class Deserializer : BaseDeserializer(Data::class) { + internal class Deserializer : BaseDeserializer(Data::class) { override fun ObjectCodec.deserialize(node: JsonNode): Data { val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return Data(bundle = it, _json = json) - } + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Data(bundle = it, _json = json) + } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Data(inline = it, _json = json) @@ -911,12 +1387,12 @@ constructor( } } - class Serializer : BaseSerializer(Data::class) { + internal class Serializer : BaseSerializer(Data::class) { override fun serialize( value: Data, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.bundle != null -> generator.writeObject(value.bundle) @@ -927,478 +1403,748 @@ constructor( } } - @JsonDeserialize(builder = Bundle.Builder::class) @NoAutoDetect class Bundle + @JsonCreator private constructor( - private val runtimeContext: JsonField, - private val location: JsonField, - private val bundleId: JsonField, - private val preview: JsonField, - private val type: JsonField, - private val additionalProperties: Map, + @JsonProperty("bundle_id") + @ExcludeMissing + private val bundleId: JsonField = JsonMissing.of(), + @JsonProperty("location") + @ExcludeMissing + private val location: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = + JsonMissing.of(), + @JsonProperty("preview") + @ExcludeMissing + private val preview: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 bundleId(): String = bundleId.getRequired("bundle_id") - fun runtimeContext(): RuntimeContext = + /** + * @throws BraintrustInvalidDataException 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 location(): CodeBundle.Location = location.getRequired("location") + + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): CodeBundle.RuntimeContext = runtimeContext.getRequired("runtime_context") - fun location(): Location = location.getRequired("location") - - fun bundleId(): String = bundleId.getRequired("bundle_id") - - /** A preview of the code */ + /** + * A preview of the code + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun preview(): Optional = Optional.ofNullable(preview.getNullable("preview")) + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun toCodeBundle(): CodeBundle = - CodeBundle.builder() - .runtimeContext(runtimeContext) - .location(location) - .bundleId(bundleId) - .preview(preview) - .build() - + /** + * Returns the raw JSON value of [bundleId]. + * + * Unlike [bundleId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("bundle_id") + @ExcludeMissing + fun _bundleId(): JsonField = bundleId + + /** + * Returns the raw JSON value of [location]. + * + * Unlike [location], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("location") + @ExcludeMissing + fun _location(): JsonField = location + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext - - @JsonProperty("location") @ExcludeMissing fun _location() = location - - @JsonProperty("bundle_id") @ExcludeMissing fun _bundleId() = bundleId - - /** A preview of the code */ - @JsonProperty("preview") @ExcludeMissing fun _preview() = preview + fun _runtimeContext(): JsonField = runtimeContext + + /** + * Returns the raw JSON value of [preview]. + * + * Unlike [preview], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("preview") + @ExcludeMissing + fun _preview(): JsonField = preview - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Bundle = apply { - if (!validated) { - runtimeContext().validate() - location() - bundleId() - preview() - type() - validated = true - } - } + fun toCodeBundle(): CodeBundle = + CodeBundle.builder() + .bundleId(bundleId) + .location(location) + .runtimeContext(runtimeContext) + .preview(preview) + .build() - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Bundle = apply { + if (validated) { + return@apply } - return other is Bundle && - this.runtimeContext == other.runtimeContext && - this.location == other.location && - this.bundleId == other.bundleId && - this.preview == other.preview && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtimeContext, - location, - bundleId, - preview, - type, - additionalProperties, - ) - } - return hashCode + bundleId() + location().validate() + runtimeContext().validate() + preview() + type() + validated = true } - override fun toString() = - "Bundle{runtimeContext=$runtimeContext, location=$location, bundleId=$bundleId, preview=$preview, type=$type, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Bundle]. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Bundle]. */ + class Builder internal constructor() { - private var runtimeContext: JsonField = JsonMissing.of() - private var location: JsonField = JsonMissing.of() - private var bundleId: JsonField = JsonMissing.of() + private var bundleId: JsonField? = null + private var location: JsonField? = null + private var runtimeContext: JsonField? = null private var preview: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(bundle: Bundle) = apply { - this.runtimeContext = bundle.runtimeContext - this.location = bundle.location - this.bundleId = bundle.bundleId - this.preview = bundle.preview - this.type = bundle.type - additionalProperties(bundle.additionalProperties) + bundleId = bundle.bundleId + location = bundle.location + runtimeContext = bundle.runtimeContext + preview = bundle.preview + type = bundle.type + additionalProperties = bundle.additionalProperties.toMutableMap() } - fun runtimeContext(runtimeContext: RuntimeContext) = - runtimeContext(JsonField.of(runtimeContext)) + fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - @JsonProperty("runtime_context") - @ExcludeMissing - fun runtimeContext(runtimeContext: JsonField) = apply { - this.runtimeContext = runtimeContext + /** + * Sets [Builder.bundleId] to an arbitrary JSON value. + * + * You should usually call [Builder.bundleId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun bundleId(bundleId: JsonField) = apply { + this.bundleId = bundleId } - fun location(location: Location) = location(JsonField.of(location)) - - @JsonProperty("location") - @ExcludeMissing - fun location(location: JsonField) = apply { + fun location(location: CodeBundle.Location) = + location(JsonField.of(location)) + + /** + * Sets [Builder.location] to an arbitrary JSON value. + * + * You should usually call [Builder.location] with a well-typed + * [CodeBundle.Location] value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun location(location: JsonField) = apply { this.location = location } - fun bundleId(bundleId: String) = bundleId(JsonField.of(bundleId)) - - @JsonProperty("bundle_id") - @ExcludeMissing - fun bundleId(bundleId: JsonField) = apply { - this.bundleId = bundleId - } + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofExperiment(experiment)`. + */ + fun location(experiment: CodeBundle.Location.Experiment) = + location(CodeBundle.Location.ofExperiment(experiment)) + + /** + * Alias for calling [location] with + * `CodeBundle.Location.ofFunction(function)`. + */ + fun location(function: CodeBundle.Location.Function) = + location(CodeBundle.Location.ofFunction(function)) + + fun runtimeContext(runtimeContext: CodeBundle.RuntimeContext) = + runtimeContext(JsonField.of(runtimeContext)) - /** A preview of the code */ - fun preview(preview: String) = preview(JsonField.of(preview)) + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [CodeBundle.RuntimeContext] value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun runtimeContext(runtimeContext: JsonField) = + apply { + this.runtimeContext = runtimeContext + } /** A preview of the code */ - @JsonProperty("preview") - @ExcludeMissing + fun preview(preview: String?) = preview(JsonField.ofNullable(preview)) + + /** Alias for calling [Builder.preview] with `preview.orElse(null)`. */ + fun preview(preview: Optional) = preview(preview.getOrNull()) + + /** + * Sets [Builder.preview] to an arbitrary JSON value. + * + * You should usually call [Builder.preview] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun preview(preview: JsonField) = apply { this.preview = preview } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Bundle]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .bundleId() + * .location() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Bundle = Bundle( - runtimeContext, - location, - bundleId, + checkRequired("bundleId", bundleId), + checkRequired("location", location), + checkRequired("runtimeContext", runtimeContext), preview, - type, - additionalProperties.toUnmodifiable(), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } class Type @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val BUNDLE = Type(JsonField.of("bundle")) + @JvmField val BUNDLE = of("bundle") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - BUNDLE, + BUNDLE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { BUNDLE, + /** + * An enum member indicating that [Type] 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) { BUNDLE -> Value.BUNDLE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { BUNDLE -> Known.BUNDLE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Bundle && bundleId == other.bundleId && location == other.location && runtimeContext == other.runtimeContext && preview == other.preview && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(bundleId, location, runtimeContext, preview, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Bundle{bundleId=$bundleId, location=$location, runtimeContext=$runtimeContext, preview=$preview, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Inline.Builder::class) @NoAutoDetect class Inline + @JsonCreator private constructor( - private val type: JsonField, - private val runtimeContext: JsonField, - private val code: JsonField, - private val additionalProperties: Map, + @JsonProperty("code") + @ExcludeMissing + private val code: JsonField = JsonMissing.of(), + @JsonProperty("runtime_context") + @ExcludeMissing + private val runtimeContext: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException 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 code(): String = code.getRequired("code") + /** + * @throws BraintrustInvalidDataException 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 runtimeContext(): RuntimeContext = runtimeContext.getRequired("runtime_context") - fun code(): String = code.getRequired("code") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [runtimeContext]. + * + * Unlike [runtimeContext], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("runtime_context") @ExcludeMissing - fun _runtimeContext() = runtimeContext + fun _runtimeContext(): JsonField = runtimeContext - @JsonProperty("code") @ExcludeMissing fun _code() = code + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Inline = apply { - if (!validated) { - type() - runtimeContext().validate() - code() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Inline = apply { + if (validated) { + return@apply } - return other is Inline && - this.type == other.type && - this.runtimeContext == other.runtimeContext && - this.code == other.code && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - runtimeContext, - code, - additionalProperties, - ) - } - return hashCode + code() + runtimeContext().validate() + type() + validated = true } - override fun toString() = - "Inline{type=$type, runtimeContext=$runtimeContext, code=$code, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Inline]. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Inline]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var runtimeContext: JsonField = JsonMissing.of() - private var code: JsonField = JsonMissing.of() + private var code: JsonField? = null + private var runtimeContext: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inline: Inline) = apply { - this.type = inline.type - this.runtimeContext = inline.runtimeContext - this.code = inline.code - additionalProperties(inline.additionalProperties) + code = inline.code + runtimeContext = inline.runtimeContext + type = inline.type + additionalProperties = inline.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) + fun code(code: String) = code(JsonField.of(code)) - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [String] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } fun runtimeContext(runtimeContext: RuntimeContext) = runtimeContext(JsonField.of(runtimeContext)) - @JsonProperty("runtime_context") - @ExcludeMissing + /** + * Sets [Builder.runtimeContext] to an arbitrary JSON value. + * + * You should usually call [Builder.runtimeContext] with a well-typed + * [RuntimeContext] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun runtimeContext(runtimeContext: JsonField) = apply { this.runtimeContext = runtimeContext } - fun code(code: String) = code(JsonField.of(code)) + fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("code") - @ExcludeMissing - fun code(code: JsonField) = apply { this.code = code } + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Inline]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .runtimeContext() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Inline = Inline( - type, - runtimeContext, - code, - additionalProperties.toUnmodifiable(), + checkRequired("code", code), + checkRequired("runtimeContext", runtimeContext), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = RuntimeContext.Builder::class) @NoAutoDetect class RuntimeContext + @JsonCreator private constructor( - private val runtime: JsonField, - private val version: JsonField, - private val additionalProperties: Map, + @JsonProperty("runtime") + @ExcludeMissing + private val runtime: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 runtime(): Runtime = runtime.getRequired("runtime") + /** + * @throws BraintrustInvalidDataException 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 version(): String = version.getRequired("version") - @JsonProperty("runtime") @ExcludeMissing fun _runtime() = runtime - - @JsonProperty("version") @ExcludeMissing fun _version() = version + /** + * Returns the raw JSON value of [runtime]. + * + * Unlike [runtime], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("runtime") + @ExcludeMissing + fun _runtime(): JsonField = runtime + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("version") + @ExcludeMissing + fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RuntimeContext = apply { - if (!validated) { - runtime() - version() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RuntimeContext = apply { + if (validated) { + return@apply } - return other is RuntimeContext && - this.runtime == other.runtime && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - runtime, - version, - additionalProperties, - ) - } - return hashCode + runtime() + version() + validated = true } - override fun toString() = - "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [RuntimeContext]. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RuntimeContext]. */ + class Builder internal constructor() { - private var runtime: JsonField = JsonMissing.of() - private var version: JsonField = JsonMissing.of() + private var runtime: JsonField? = null + private var version: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(runtimeContext: RuntimeContext) = apply { - this.runtime = runtimeContext.runtime - this.version = runtimeContext.version - additionalProperties(runtimeContext.additionalProperties) + runtime = runtimeContext.runtime + version = runtimeContext.version + additionalProperties = + runtimeContext.additionalProperties.toMutableMap() } fun runtime(runtime: Runtime) = runtime(JsonField.of(runtime)) - @JsonProperty("runtime") - @ExcludeMissing + /** + * Sets [Builder.runtime] to an arbitrary JSON value. + * + * You should usually call [Builder.runtime] with a well-typed [Runtime] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun runtime(runtime: JsonField) = apply { this.runtime = runtime } fun version(version: String) = version(JsonField.of(version)) - @JsonProperty("version") - @ExcludeMissing + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun version(version: JsonField) = apply { this.version = version } @@ -1406,67 +2152,106 @@ constructor( fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RuntimeContext]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .runtime() + * .version() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RuntimeContext = RuntimeContext( - runtime, - version, - additionalProperties.toUnmodifiable(), + checkRequired("runtime", runtime), + checkRequired("version", version), + additionalProperties.toImmutable(), ) } class Runtime @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Runtime && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val NODE = Runtime(JsonField.of("node")) + @JvmField val NODE = of("node") - @JvmField val PYTHON = Runtime(JsonField.of("python")) + @JvmField val PYTHON = of("python") @JvmStatic fun of(value: String) = Runtime(JsonField.of(value)) } + /** An enum containing [Runtime]'s known values. */ enum class Known { NODE, PYTHON, } + /** + * An enum containing [Runtime]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Runtime] 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 { NODE, PYTHON, + /** + * An enum member indicating that [Runtime] 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) { NODE -> Value.NODE @@ -1474,6 +2259,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value + * is a not a known member. + */ fun known(): Known = when (this) { NODE -> Known.NODE @@ -1484,215 +2278,403 @@ constructor( ) } - fun asString(): String = _value().asStringOrThrow() - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + return /* spotless:off */ other is Runtime && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is RuntimeContext && runtime == other.runtime && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(runtime, version, additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = + "RuntimeContext{runtime=$runtime, version=$version, additionalProperties=$additionalProperties}" + } + + class Type + @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 INLINE = Type(JsonField.of("inline")) + @JvmField val INLINE = of("inline") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - INLINE, + INLINE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { INLINE, + /** + * An enum member indicating that [Type] 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) { INLINE -> Value.INLINE 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { INLINE -> Known.INLINE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - return other is Type && this.value == other.value - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun hashCode() = value.hashCode() + return /* spotless:off */ other is Inline && code == other.code && runtimeContext == other.runtimeContext && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } - override fun toString() = value.toString() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(code, runtimeContext, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Inline{code=$code, runtimeContext=$runtimeContext, type=$type, additionalProperties=$additionalProperties}" + } + } + + class Type @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 CODE = Type(JsonField.of("code")) + @JvmField val CODE = of("code") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - CODE, + CODE } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { CODE, + /** + * An enum member indicating that [Type] 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) { CODE -> Value.CODE 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { CODE -> Known.CODE else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Code && data == other.data && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(data, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Code{data=$data, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") + /** + * 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 - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -1700,139 +2682,161 @@ constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - private var hashCode: Int = 0 + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + override fun hashCode() = value.hashCode() - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true - } + override fun toString() = value.toString() } - fun toBuilder() = Builder().from(this) - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ - class Builder { + override fun hashCode(): Int = hashCode - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" + } + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return /* spotless:off */ other is FunctionUpdateParams && functionId == other.functionId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(functionId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } - } - } + override fun toString() = + "FunctionUpdateParams{functionId=$functionId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Group.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Group.kt index e6427910..4ab379e6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Group.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Group.kt @@ -7,214 +7,292 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * A group is a collection of users which can be assigned an ACL * * Groups can consist of individual users, as well as a set of groups they inherit from */ -@JsonDeserialize(builder = Group.Builder::class) @NoAutoDetect class Group +@JsonCreator private constructor( - private val id: JsonField, - private val orgId: JsonField, - private val userId: JsonField, - private val created: JsonField, - private val name: JsonField, - private val description: JsonField, - private val deletedAt: JsonField, - private val memberUsers: JsonField>, - private val memberGroups: JsonField>, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_groups") + @ExcludeMissing + private val memberGroups: JsonField> = JsonMissing.of(), + @JsonProperty("member_users") + @ExcludeMissing + private val memberUsers: JsonField> = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the group */ + /** + * Unique identifier for the group + * + * @throws BraintrustInvalidDataException 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") + /** + * Name of the group + * + * @throws BraintrustInvalidDataException 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") + /** * Unique id for the organization that the group belongs under * * It is forbidden to change the org after creating a group + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") - /** Identifies the user who created the group */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - - /** Date of group creation */ + /** + * Date of group creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Name of the group */ - fun name(): String = name.getRequired("name") - - /** Textual description of the group */ - fun description(): Optional = - Optional.ofNullable(description.getNullable("description")) - - /** Date of group deletion, or null if the group is still active */ + /** + * Date of group deletion, or null if the group is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun deletedAt(): Optional = Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Ids of users which belong to this group */ - fun memberUsers(): Optional> = - Optional.ofNullable(memberUsers.getNullable("member_users")) + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) /** * Ids of the groups this group inherits from * * An inheriting group has all the users contained in its member groups, as well as all of their * inherited users + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun memberGroups(): Optional> = Optional.ofNullable(memberGroups.getNullable("member_groups")) - /** Unique identifier for the group */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * Ids of users which belong to this group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberUsers(): Optional> = + Optional.ofNullable(memberUsers.getNullable("member_users")) /** - * Unique id for the organization that the group belongs under + * Identifies the user who created the group * - * It is forbidden to change the org after creating a group + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Identifies the user who created the group */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * 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 - /** Date of group creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 - /** Name of the group */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId - /** Textual description of the group */ - @JsonProperty("description") @ExcludeMissing fun _description() = description + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** Date of group deletion, or null if the group is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt - /** Ids of users which belong to this group */ - @JsonProperty("member_users") @ExcludeMissing fun _memberUsers() = memberUsers + /** + * 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 /** - * Ids of the groups this group inherits from + * Returns the raw JSON value of [memberGroups]. * - * An inheriting group has all the users contained in its member groups, as well as all of their - * inherited users + * Unlike [memberGroups], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_groups") + @ExcludeMissing + fun _memberGroups(): JsonField> = memberGroups + + /** + * Returns the raw JSON value of [memberUsers]. + * + * Unlike [memberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_users") + @ExcludeMissing + fun _memberUsers(): JsonField> = memberUsers + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("member_groups") @ExcludeMissing fun _memberGroups() = memberGroups + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Group = apply { - if (!validated) { - id() - orgId() - userId() - created() - name() - description() - deletedAt() - memberUsers() - memberGroups() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Group = apply { + if (validated) { + return@apply } - return other is Group && - this.id == other.id && - this.orgId == other.orgId && - this.userId == other.userId && - this.created == other.created && - this.name == other.name && - this.description == other.description && - this.deletedAt == other.deletedAt && - this.memberUsers == other.memberUsers && - this.memberGroups == other.memberGroups && - this.additionalProperties == other.additionalProperties + id() + name() + orgId() + created() + deletedAt() + description() + memberGroups() + memberUsers() + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - orgId, - userId, - created, - name, - description, - deletedAt, - memberUsers, - memberGroups, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Group{id=$id, orgId=$orgId, userId=$userId, created=$created, name=$name, description=$description, deletedAt=$deletedAt, memberUsers=$memberUsers, memberGroups=$memberGroups, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Group]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Group]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var orgId: JsonField? = null private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() private var deletedAt: JsonField = JsonMissing.of() - private var memberUsers: JsonField> = JsonMissing.of() - private var memberGroups: JsonField> = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var memberGroups: JsonField>? = null + private var memberUsers: JsonField>? = null + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(group: Group) = apply { - this.id = group.id - this.orgId = group.orgId - this.userId = group.userId - this.created = group.created - this.name = group.name - this.description = group.description - this.deletedAt = group.deletedAt - this.memberUsers = group.memberUsers - this.memberGroups = group.memberGroups - additionalProperties(group.additionalProperties) + id = group.id + name = group.name + orgId = group.orgId + created = group.created + deletedAt = group.deletedAt + description = group.description + memberGroups = group.memberGroups.map { it.toMutableList() } + memberUsers = group.memberUsers.map { it.toMutableList() } + userId = group.userId + additionalProperties = group.additionalProperties.toMutableMap() } /** Unique identifier for the group */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the group */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } + + /** Name of the group */ + 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 } /** * Unique id for the organization that the group belongs under @@ -224,110 +302,199 @@ private constructor( fun orgId(orgId: String) = orgId(JsonField.of(orgId)) /** - * Unique id for the organization that the group belongs under + * Sets [Builder.orgId] to an arbitrary JSON value. * - * It is forbidden to change the org after creating a group + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("org_id") - @ExcludeMissing fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - /** Identifies the user who created the group */ - fun userId(userId: String) = userId(JsonField.of(userId)) - - /** Identifies the user who created the group */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } - /** Date of group creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) - /** Date of group creation */ - @JsonProperty("created") - @ExcludeMissing + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } - /** Name of the group */ - fun name(name: String) = name(JsonField.of(name)) + /** Date of group deletion, or null if the group is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) - /** Name of the group */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) - /** Textual description of the group */ - fun description(description: String) = description(JsonField.of(description)) + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } /** Textual description of the group */ - @JsonProperty("description") - @ExcludeMissing + 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 } - /** Date of group deletion, or null if the group is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) + /** + * Ids of the groups this group inherits from + * + * An inheriting group has all the users contained in its member groups, as well as all of + * their inherited users + */ + fun memberGroups(memberGroups: List?) = + memberGroups(JsonField.ofNullable(memberGroups)) - /** Date of group deletion, or null if the group is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing - fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + /** Alias for calling [Builder.memberGroups] with `memberGroups.orElse(null)`. */ + fun memberGroups(memberGroups: Optional>) = + memberGroups(memberGroups.getOrNull()) - /** Ids of users which belong to this group */ - fun memberUsers(memberUsers: List) = memberUsers(JsonField.of(memberUsers)) + /** + * Sets [Builder.memberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.memberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberGroups(memberGroups: JsonField>) = apply { + this.memberGroups = memberGroups.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberGroup(memberGroup: String) = apply { + memberGroups = + (memberGroups ?: JsonField.of(mutableListOf())).also { + checkKnown("memberGroups", it).add(memberGroup) + } + } /** Ids of users which belong to this group */ - @JsonProperty("member_users") - @ExcludeMissing + fun memberUsers(memberUsers: List?) = memberUsers(JsonField.ofNullable(memberUsers)) + + /** Alias for calling [Builder.memberUsers] with `memberUsers.orElse(null)`. */ + fun memberUsers(memberUsers: Optional>) = memberUsers(memberUsers.getOrNull()) + + /** + * Sets [Builder.memberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.memberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun memberUsers(memberUsers: JsonField>) = apply { - this.memberUsers = memberUsers + this.memberUsers = memberUsers.map { it.toMutableList() } } /** - * Ids of the groups this group inherits from + * Adds a single [String] to [memberUsers]. * - * An inheriting group has all the users contained in its member groups, as well as all of - * their inherited users + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun memberGroups(memberGroups: List) = memberGroups(JsonField.of(memberGroups)) + fun addMemberUser(memberUser: String) = apply { + memberUsers = + (memberUsers ?: JsonField.of(mutableListOf())).also { + checkKnown("memberUsers", it).add(memberUser) + } + } + + /** Identifies the user who created the group */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) /** - * Ids of the groups this group inherits from + * Sets [Builder.userId] to an arbitrary JSON value. * - * An inheriting group has all the users contained in its member groups, as well as all of - * their inherited users + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("member_groups") - @ExcludeMissing - fun memberGroups(memberGroups: JsonField>) = apply { - this.memberGroups = memberGroups - } + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Group]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Group = Group( - id, - orgId, - userId, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("orgId", orgId), created, - name, - description, deletedAt, - memberUsers.map { it.toUnmodifiable() }, - memberGroups.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + description, + (memberGroups ?: JsonMissing.of()).map { it.toImmutable() }, + (memberUsers ?: JsonMissing.of()).map { it.toImmutable() }, + userId, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Group && id == other.id && name == other.name && orgId == other.orgId && created == other.created && deletedAt == other.deletedAt && description == other.description && memberGroups == other.memberGroups && memberUsers == other.memberUsers && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, orgId, created, deletedAt, description, memberGroups, memberUsers, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Group{id=$id, name=$name, orgId=$orgId, created=$created, deletedAt=$deletedAt, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupCreateParams.kt index 50bdabcf..cda2eae4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupCreateParams.kt @@ -3,161 +3,324 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new group. If there is an existing group with the same name as the one specified in the + * request, will return the existing group unmodified + */ class GroupCreateParams -constructor( - private val name: String, - private val description: String?, - private val memberGroups: List?, - private val memberUsers: List?, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun description(): Optional = Optional.ofNullable(description) - - fun memberGroups(): Optional> = Optional.ofNullable(memberGroups) - - fun memberUsers(): Optional> = Optional.ofNullable(memberUsers) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): GroupCreateBody { - return GroupCreateBody( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the group + * + * @throws BraintrustInvalidDataException 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() + + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Ids of the groups this group inherits from + * + * An inheriting group has all the users contained in its member groups, as well as all of their + * inherited users + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberGroups(): Optional> = body.memberGroups() + + /** + * Ids of users which belong to this group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberUsers(): Optional> = body.memberUsers() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * group belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [memberGroups]. + * + * Unlike [memberGroups], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberGroups(): JsonField> = body._memberGroups() + + /** + * Returns the raw JSON value of [memberUsers]. + * + * Unlike [memberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberUsers(): JsonField> = body._memberUsers() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = GroupCreateBody.Builder::class) @NoAutoDetect - class GroupCreateBody - internal constructor( - private val name: String?, - private val description: String?, - private val memberGroups: List?, - private val memberUsers: List?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_groups") + @ExcludeMissing + private val memberGroups: JsonField> = JsonMissing.of(), + @JsonProperty("member_users") + @ExcludeMissing + private val memberUsers: JsonField> = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the group */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the group + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the group */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) /** * Ids of the groups this group inherits from * * An inheriting group has all the users contained in its member groups, as well as all of * their inherited users + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("member_groups") fun memberGroups(): List? = memberGroups + fun memberGroups(): Optional> = + Optional.ofNullable(memberGroups.getNullable("member_groups")) - /** Ids of users which belong to this group */ - @JsonProperty("member_users") fun memberUsers(): List? = memberUsers + /** + * Ids of users which belong to this group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun memberUsers(): Optional> = + Optional.ofNullable(memberUsers.getNullable("member_users")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @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 [memberGroups]. + * + * Unlike [memberGroups], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("member_groups") + @ExcludeMissing + fun _memberGroups(): JsonField> = memberGroups + + /** + * Returns the raw JSON value of [memberUsers]. + * + * Unlike [memberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_users") + @ExcludeMissing + fun _memberUsers(): JsonField> = memberUsers + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is GroupCreateBody && - this.name == other.name && - this.description == other.description && - this.memberGroups == other.memberGroups && - this.memberUsers == other.memberUsers && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalProperties, - ) - } - return hashCode + name() + description() + memberGroups() + memberUsers() + orgName() + validated = true } - override fun toString() = - "GroupCreateBody{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberGroups: List? = null - private var memberUsers: List? = null - private var orgName: String? = null + private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var memberGroups: JsonField>? = null + private var memberUsers: JsonField>? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(groupCreateBody: GroupCreateBody) = apply { - this.name = groupCreateBody.name - this.description = groupCreateBody.description - this.memberGroups = groupCreateBody.memberGroups - this.memberUsers = groupCreateBody.memberUsers - this.orgName = groupCreateBody.orgName - additionalProperties(groupCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + description = body.description + memberGroups = body.memberGroups.map { it.toMutableList() } + memberUsers = body.memberUsers.map { it.toMutableList() } + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the group */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Textual description of the group */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** * Ids of the groups this group inherits from @@ -165,123 +328,201 @@ constructor( * An inheriting group has all the users contained in its member groups, as well as all * of their inherited users */ - @JsonProperty("member_groups") - fun memberGroups(memberGroups: List) = apply { - this.memberGroups = memberGroups + fun memberGroups(memberGroups: List?) = + memberGroups(JsonField.ofNullable(memberGroups)) + + /** Alias for calling [Builder.memberGroups] with `memberGroups.orElse(null)`. */ + fun memberGroups(memberGroups: Optional>) = + memberGroups(memberGroups.getOrNull()) + + /** + * Sets [Builder.memberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.memberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberGroups(memberGroups: JsonField>) = apply { + this.memberGroups = memberGroups.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberGroup(memberGroup: String) = apply { + memberGroups = + (memberGroups ?: JsonField.of(mutableListOf())).also { + checkKnown("memberGroups", it).add(memberGroup) + } } /** Ids of users which belong to this group */ - @JsonProperty("member_users") - fun memberUsers(memberUsers: List) = apply { this.memberUsers = memberUsers } + fun memberUsers(memberUsers: List?) = + memberUsers(JsonField.ofNullable(memberUsers)) + + /** Alias for calling [Builder.memberUsers] with `memberUsers.orElse(null)`. */ + fun memberUsers(memberUsers: Optional>) = + memberUsers(memberUsers.getOrNull()) + + /** + * Sets [Builder.memberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.memberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberUsers(memberUsers: JsonField>) = apply { + this.memberUsers = memberUsers.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberUser(memberUser: String) = apply { + memberUsers = + (memberUsers ?: JsonField.of(mutableListOf())).also { + checkKnown("memberUsers", it).add(memberUser) + } + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): GroupCreateBody = - GroupCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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, - memberGroups?.toUnmodifiable(), - memberUsers?.toUnmodifiable(), + (memberGroups ?: JsonMissing.of()).map { it.toImmutable() }, + (memberUsers ?: JsonMissing.of()).map { it.toImmutable() }, orgName, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && description == other.description && memberGroups == other.memberGroups && memberUsers == other.memberUsers && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is GroupCreateParams && - this.name == other.name && - this.description == other.description && - this.memberGroups == other.memberGroups && - this.memberUsers == other.memberUsers && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, description, memberGroups, memberUsers, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "GroupCreateParams{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GroupCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberGroups: MutableList = mutableListOf() - private var memberUsers: MutableList = mutableListOf() - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(groupCreateParams: GroupCreateParams) = apply { - this.name = groupCreateParams.name - this.description = groupCreateParams.description - this.memberGroups(groupCreateParams.memberGroups ?: listOf()) - this.memberUsers(groupCreateParams.memberUsers ?: listOf()) - this.orgName = groupCreateParams.orgName - additionalQueryParams(groupCreateParams.additionalQueryParams) - additionalHeaders(groupCreateParams.additionalHeaders) - additionalBodyProperties(groupCreateParams.additionalBodyProperties) + body = groupCreateParams.body.toBuilder() + additionalHeaders = groupCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = groupCreateParams.additionalQueryParams.toBuilder() } /** Name of the group */ - fun name(name: String) = apply { this.name = 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) } /** Textual description of the group */ - fun description(description: String) = apply { this.description = description } + 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) } /** * Ids of the groups this group inherits from @@ -289,99 +530,219 @@ constructor( * An inheriting group has all the users contained in its member groups, as well as all of * their inherited users */ - fun memberGroups(memberGroups: List) = apply { - this.memberGroups.clear() - this.memberGroups.addAll(memberGroups) + fun memberGroups(memberGroups: List?) = apply { body.memberGroups(memberGroups) } + + /** Alias for calling [Builder.memberGroups] with `memberGroups.orElse(null)`. */ + fun memberGroups(memberGroups: Optional>) = + memberGroups(memberGroups.getOrNull()) + + /** + * Sets [Builder.memberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.memberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberGroups(memberGroups: JsonField>) = apply { + body.memberGroups(memberGroups) } /** - * Ids of the groups this group inherits from + * Adds a single [String] to [memberGroups]. * - * An inheriting group has all the users contained in its member groups, as well as all of - * their inherited users + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addMemberGroup(memberGroup: String) = apply { this.memberGroups.add(memberGroup) } + fun addMemberGroup(memberGroup: String) = apply { body.addMemberGroup(memberGroup) } /** Ids of users which belong to this group */ - fun memberUsers(memberUsers: List) = apply { - this.memberUsers.clear() - this.memberUsers.addAll(memberUsers) + fun memberUsers(memberUsers: List?) = apply { body.memberUsers(memberUsers) } + + /** Alias for calling [Builder.memberUsers] with `memberUsers.orElse(null)`. */ + fun memberUsers(memberUsers: Optional>) = memberUsers(memberUsers.getOrNull()) + + /** + * Sets [Builder.memberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.memberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberUsers(memberUsers: JsonField>) = apply { + body.memberUsers(memberUsers) } - /** Ids of users which belong to this group */ - fun addMemberUser(memberUser: String) = apply { this.memberUsers.add(memberUser) } + /** + * Adds a single [String] to [memberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberUser(memberUser: String) = apply { body.addMemberUser(memberUser) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [GroupCreateParams]. + * + * 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(): GroupCreateParams = GroupCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - description, - if (memberGroups.size == 0) null else memberGroups.toUnmodifiable(), - if (memberUsers.size == 0) null else memberUsers.toUnmodifiable(), - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GroupCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupDeleteParams.kt index 275bba9f..07473a4f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a group object by its id */ class GroupDeleteParams -constructor( +private constructor( private val groupId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Group id */ fun groupId(): String = groupId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is GroupDeleteParams && - this.groupId == other.groupId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - groupId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "GroupDeleteParams{groupId=$groupId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GroupDeleteParams]. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var groupId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(groupDeleteParams: GroupDeleteParams) = apply { - this.groupId = groupDeleteParams.groupId - additionalQueryParams(groupDeleteParams.additionalQueryParams) - additionalHeaders(groupDeleteParams.additionalHeaders) - additionalBodyProperties(groupDeleteParams.additionalBodyProperties) + groupId = groupDeleteParams.groupId + additionalHeaders = groupDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = groupDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = groupDeleteParams.additionalBodyProperties.toMutableMap() } /** Group id */ fun groupId(groupId: String) = apply { this.groupId = groupId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [GroupDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): GroupDeleteParams = GroupDeleteParams( - checkNotNull(groupId) { "`groupId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("groupId", groupId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupDeleteParams && groupId == other.groupId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(groupId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "GroupDeleteParams{groupId=$groupId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPage.kt index 9d3d9ceb..33debe68 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.GroupService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all groups. The groups are sorted by creation date, with the most recently-created + * groups coming first + */ class GroupListPage private constructor( private val groupsService: GroupService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is GroupListPage && - this.groupsService == other.groupsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is GroupListPage && groupsService == other.groupsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - groupsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(groupsService, params, response) /* spotless:on */ override fun toString() = "GroupListPage{groupsService=$groupsService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(groupsService: GroupService, params: GroupListParams, response: Response) = - GroupListPage( - groupsService, - params, - response, - ) + GroupListPage(groupsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "GroupListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [GroupListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: GroupListPage, - ) : Iterable { + class AutoPager(private val firstPage: GroupListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPageAsync.kt index cc058b58..7b8849b1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.GroupServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all groups. The groups are sorted by creation date, with the most recently-created + * groups coming first + */ class GroupListPageAsync private constructor( private val groupsService: GroupServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is GroupListPageAsync && - this.groupsService == other.groupsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is GroupListPageAsync && groupsService == other.groupsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - groupsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(groupsService, params, response) /* spotless:on */ override fun toString() = "GroupListPageAsync{groupsService=$groupsService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(groupsService: GroupServiceAsync, params: GroupListParams, response: Response) = - GroupListPageAsync( - groupsService, - params, - response, - ) + GroupListPageAsync(groupsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "GroupListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [GroupListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: GroupListPageAsync, - ) { + class AutoPager(private val firstPage: GroupListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Group) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListParams.kt index 99922e46..94cc7e6a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,91 +20,99 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all groups. The groups are sorted by creation date, with the most recently-created + * groups coming first + */ class GroupListParams -constructor( +private constructor( private val endingBefore: String?, private val groupName: String?, private val ids: Ids?, private val limit: Long?, private val orgName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** Name of the group to search for */ fun groupName(): Optional = Optional.ofNullable(groupName) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.groupName?.let { params.put("group_name", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is GroupListParams && - this.endingBefore == other.endingBefore && - this.groupName == other.groupName && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - groupName, - ids, - limit, - orgName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "GroupListParams{endingBefore=$endingBefore, groupName=$groupName, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + groupName?.let { put("group_name", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): GroupListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [GroupListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var groupName: String? = null @@ -111,19 +120,19 @@ constructor( private var limit: Long? = null private var orgName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(groupListParams: GroupListParams) = apply { - this.endingBefore = groupListParams.endingBefore - this.groupName = groupListParams.groupName - this.ids = groupListParams.ids - this.limit = groupListParams.limit - this.orgName = groupListParams.orgName - this.startingAfter = groupListParams.startingAfter - additionalQueryParams(groupListParams.additionalQueryParams) - additionalHeaders(groupListParams.additionalHeaders) + endingBefore = groupListParams.endingBefore + groupName = groupListParams.groupName + ids = groupListParams.ids + limit = groupListParams.limit + orgName = groupListParams.orgName + startingAfter = groupListParams.startingAfter + additionalHeaders = groupListParams.additionalHeaders.toBuilder() + additionalQueryParams = groupListParams.additionalQueryParams.toBuilder() } /** @@ -133,34 +142,50 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } + + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** Name of the group to search for */ - fun groupName(groupName: String) = apply { this.groupName = groupName } + fun groupName(groupName: String?) = apply { this.groupName = groupName } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.groupName] with `groupName.orElse(null)`. */ + fun groupName(groupName: Optional) = groupName(groupName.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** * Pagination cursor id. @@ -169,48 +194,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [GroupListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): GroupListParams = GroupListParams( endingBefore, @@ -219,11 +311,15 @@ constructor( limit, orgName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -233,8 +329,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -257,35 +351,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -294,21 +376,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -320,12 +413,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -336,4 +429,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupListParams && endingBefore == other.endingBefore && groupName == other.groupName && ids == other.ids && limit == other.limit && orgName == other.orgName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, groupName, ids, limit, orgName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GroupListParams{endingBefore=$endingBefore, groupName=$groupName, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupReplaceParams.kt index c7f5ad54..b11f2119 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupReplaceParams.kt @@ -3,161 +3,324 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace group. If there is an existing group with the same name as the one specified in + * the request, will replace the existing group with the provided fields + */ class GroupReplaceParams -constructor( - private val name: String, - private val description: String?, - private val memberGroups: List?, - private val memberUsers: List?, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun description(): Optional = Optional.ofNullable(description) - - fun memberGroups(): Optional> = Optional.ofNullable(memberGroups) - - fun memberUsers(): Optional> = Optional.ofNullable(memberUsers) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): GroupReplaceBody { - return GroupReplaceBody( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the group + * + * @throws BraintrustInvalidDataException 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() + + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Ids of the groups this group inherits from + * + * An inheriting group has all the users contained in its member groups, as well as all of their + * inherited users + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberGroups(): Optional> = body.memberGroups() + + /** + * Ids of users which belong to this group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberUsers(): Optional> = body.memberUsers() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * group belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [memberGroups]. + * + * Unlike [memberGroups], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberGroups(): JsonField> = body._memberGroups() + + /** + * Returns the raw JSON value of [memberUsers]. + * + * Unlike [memberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberUsers(): JsonField> = body._memberUsers() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = GroupReplaceBody.Builder::class) @NoAutoDetect - class GroupReplaceBody - internal constructor( - private val name: String?, - private val description: String?, - private val memberGroups: List?, - private val memberUsers: List?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_groups") + @ExcludeMissing + private val memberGroups: JsonField> = JsonMissing.of(), + @JsonProperty("member_users") + @ExcludeMissing + private val memberUsers: JsonField> = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the group */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the group + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the group */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) /** * Ids of the groups this group inherits from * * An inheriting group has all the users contained in its member groups, as well as all of * their inherited users + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("member_groups") fun memberGroups(): List? = memberGroups + fun memberGroups(): Optional> = + Optional.ofNullable(memberGroups.getNullable("member_groups")) - /** Ids of users which belong to this group */ - @JsonProperty("member_users") fun memberUsers(): List? = memberUsers + /** + * Ids of users which belong to this group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun memberUsers(): Optional> = + Optional.ofNullable(memberUsers.getNullable("member_users")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @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 [memberGroups]. + * + * Unlike [memberGroups], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("member_groups") + @ExcludeMissing + fun _memberGroups(): JsonField> = memberGroups + + /** + * Returns the raw JSON value of [memberUsers]. + * + * Unlike [memberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_users") + @ExcludeMissing + fun _memberUsers(): JsonField> = memberUsers + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is GroupReplaceBody && - this.name == other.name && - this.description == other.description && - this.memberGroups == other.memberGroups && - this.memberUsers == other.memberUsers && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalProperties, - ) - } - return hashCode + name() + description() + memberGroups() + memberUsers() + orgName() + validated = true } - override fun toString() = - "GroupReplaceBody{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberGroups: List? = null - private var memberUsers: List? = null - private var orgName: String? = null + private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var memberGroups: JsonField>? = null + private var memberUsers: JsonField>? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(groupReplaceBody: GroupReplaceBody) = apply { - this.name = groupReplaceBody.name - this.description = groupReplaceBody.description - this.memberGroups = groupReplaceBody.memberGroups - this.memberUsers = groupReplaceBody.memberUsers - this.orgName = groupReplaceBody.orgName - additionalProperties(groupReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + description = body.description + memberGroups = body.memberGroups.map { it.toMutableList() } + memberUsers = body.memberUsers.map { it.toMutableList() } + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the group */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Textual description of the group */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** * Ids of the groups this group inherits from @@ -165,123 +328,201 @@ constructor( * An inheriting group has all the users contained in its member groups, as well as all * of their inherited users */ - @JsonProperty("member_groups") - fun memberGroups(memberGroups: List) = apply { - this.memberGroups = memberGroups + fun memberGroups(memberGroups: List?) = + memberGroups(JsonField.ofNullable(memberGroups)) + + /** Alias for calling [Builder.memberGroups] with `memberGroups.orElse(null)`. */ + fun memberGroups(memberGroups: Optional>) = + memberGroups(memberGroups.getOrNull()) + + /** + * Sets [Builder.memberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.memberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberGroups(memberGroups: JsonField>) = apply { + this.memberGroups = memberGroups.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberGroup(memberGroup: String) = apply { + memberGroups = + (memberGroups ?: JsonField.of(mutableListOf())).also { + checkKnown("memberGroups", it).add(memberGroup) + } } /** Ids of users which belong to this group */ - @JsonProperty("member_users") - fun memberUsers(memberUsers: List) = apply { this.memberUsers = memberUsers } + fun memberUsers(memberUsers: List?) = + memberUsers(JsonField.ofNullable(memberUsers)) + + /** Alias for calling [Builder.memberUsers] with `memberUsers.orElse(null)`. */ + fun memberUsers(memberUsers: Optional>) = + memberUsers(memberUsers.getOrNull()) + + /** + * Sets [Builder.memberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.memberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberUsers(memberUsers: JsonField>) = apply { + this.memberUsers = memberUsers.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberUser(memberUser: String) = apply { + memberUsers = + (memberUsers ?: JsonField.of(mutableListOf())).also { + checkKnown("memberUsers", it).add(memberUser) + } + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): GroupReplaceBody = - GroupReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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, - memberGroups?.toUnmodifiable(), - memberUsers?.toUnmodifiable(), + (memberGroups ?: JsonMissing.of()).map { it.toImmutable() }, + (memberUsers ?: JsonMissing.of()).map { it.toImmutable() }, orgName, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && description == other.description && memberGroups == other.memberGroups && memberUsers == other.memberUsers && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is GroupReplaceParams && - this.name == other.name && - this.description == other.description && - this.memberGroups == other.memberGroups && - this.memberUsers == other.memberUsers && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, description, memberGroups, memberUsers, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - description, - memberGroups, - memberUsers, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "GroupReplaceParams{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, description=$description, memberGroups=$memberGroups, memberUsers=$memberUsers, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GroupReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupReplaceParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberGroups: MutableList = mutableListOf() - private var memberUsers: MutableList = mutableListOf() - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(groupReplaceParams: GroupReplaceParams) = apply { - this.name = groupReplaceParams.name - this.description = groupReplaceParams.description - this.memberGroups(groupReplaceParams.memberGroups ?: listOf()) - this.memberUsers(groupReplaceParams.memberUsers ?: listOf()) - this.orgName = groupReplaceParams.orgName - additionalQueryParams(groupReplaceParams.additionalQueryParams) - additionalHeaders(groupReplaceParams.additionalHeaders) - additionalBodyProperties(groupReplaceParams.additionalBodyProperties) + body = groupReplaceParams.body.toBuilder() + additionalHeaders = groupReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = groupReplaceParams.additionalQueryParams.toBuilder() } /** Name of the group */ - fun name(name: String) = apply { this.name = 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) } /** Textual description of the group */ - fun description(description: String) = apply { this.description = description } + 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) } /** * Ids of the groups this group inherits from @@ -289,99 +530,219 @@ constructor( * An inheriting group has all the users contained in its member groups, as well as all of * their inherited users */ - fun memberGroups(memberGroups: List) = apply { - this.memberGroups.clear() - this.memberGroups.addAll(memberGroups) + fun memberGroups(memberGroups: List?) = apply { body.memberGroups(memberGroups) } + + /** Alias for calling [Builder.memberGroups] with `memberGroups.orElse(null)`. */ + fun memberGroups(memberGroups: Optional>) = + memberGroups(memberGroups.getOrNull()) + + /** + * Sets [Builder.memberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.memberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberGroups(memberGroups: JsonField>) = apply { + body.memberGroups(memberGroups) } /** - * Ids of the groups this group inherits from + * Adds a single [String] to [memberGroups]. * - * An inheriting group has all the users contained in its member groups, as well as all of - * their inherited users + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addMemberGroup(memberGroup: String) = apply { this.memberGroups.add(memberGroup) } + fun addMemberGroup(memberGroup: String) = apply { body.addMemberGroup(memberGroup) } /** Ids of users which belong to this group */ - fun memberUsers(memberUsers: List) = apply { - this.memberUsers.clear() - this.memberUsers.addAll(memberUsers) + fun memberUsers(memberUsers: List?) = apply { body.memberUsers(memberUsers) } + + /** Alias for calling [Builder.memberUsers] with `memberUsers.orElse(null)`. */ + fun memberUsers(memberUsers: Optional>) = memberUsers(memberUsers.getOrNull()) + + /** + * Sets [Builder.memberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.memberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberUsers(memberUsers: JsonField>) = apply { + body.memberUsers(memberUsers) } - /** Ids of users which belong to this group */ - fun addMemberUser(memberUser: String) = apply { this.memberUsers.add(memberUser) } + /** + * Adds a single [String] to [memberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberUser(memberUser: String) = apply { body.addMemberUser(memberUser) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the group belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [GroupReplaceParams]. + * + * 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(): GroupReplaceParams = GroupReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - description, - if (memberGroups.size == 0) null else memberGroups.toUnmodifiable(), - if (memberUsers.size == 0) null else memberUsers.toUnmodifiable(), - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GroupReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupRetrieveParams.kt index 7a68c3d6..1105cf21 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a group object by its id */ class GroupRetrieveParams -constructor( +private constructor( private val groupId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Group id */ fun groupId(): String = groupId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is GroupRetrieveParams && - this.groupId == other.groupId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - groupId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "GroupRetrieveParams{groupId=$groupId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GroupRetrieveParams]. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var groupId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(groupRetrieveParams: GroupRetrieveParams) = apply { - this.groupId = groupRetrieveParams.groupId - additionalQueryParams(groupRetrieveParams.additionalQueryParams) - additionalHeaders(groupRetrieveParams.additionalHeaders) + groupId = groupRetrieveParams.groupId + additionalHeaders = groupRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = groupRetrieveParams.additionalQueryParams.toBuilder() } /** Group id */ fun groupId(groupId: String) = apply { this.groupId = groupId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [GroupRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): GroupRetrieveParams = GroupRetrieveParams( - checkNotNull(groupId) { "`groupId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("groupId", groupId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupRetrieveParams && groupId == other.groupId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(groupId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GroupRetrieveParams{groupId=$groupId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupUpdateParams.kt index ad6adecc..8009fc68 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/GroupUpdateParams.kt @@ -3,61 +3,145 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a group object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class GroupUpdateParams -constructor( +private constructor( private val groupId: String, - private val addMemberGroups: List?, - private val addMemberUsers: List?, - private val description: String?, - private val name: String?, - private val removeMemberGroups: List?, - private val removeMemberUsers: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Group id */ fun groupId(): String = groupId - fun addMemberGroups(): Optional> = Optional.ofNullable(addMemberGroups) - - fun addMemberUsers(): Optional> = Optional.ofNullable(addMemberUsers) - - fun description(): Optional = Optional.ofNullable(description) - - fun name(): Optional = Optional.ofNullable(name) - - fun removeMemberGroups(): Optional> = Optional.ofNullable(removeMemberGroups) - - fun removeMemberUsers(): Optional> = Optional.ofNullable(removeMemberUsers) - - @JvmSynthetic - internal fun getBody(): GroupUpdateBody { - return GroupUpdateBody( - addMemberGroups, - addMemberUsers, - description, - name, - removeMemberGroups, - removeMemberUsers, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * A list of group IDs to add to the group's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun addMemberGroups(): Optional> = body.addMemberGroups() + + /** + * A list of user IDs to add to the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun addMemberUsers(): Optional> = body.addMemberUsers() + + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * A list of group IDs to remove from the group's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun removeMemberGroups(): Optional> = body.removeMemberGroups() + + /** + * A list of user IDs to remove from the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun removeMemberUsers(): Optional> = body.removeMemberUsers() + + /** + * Returns the raw JSON value of [addMemberGroups]. + * + * Unlike [addMemberGroups], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _addMemberGroups(): JsonField> = body._addMemberGroups() + + /** + * Returns the raw JSON value of [addMemberUsers]. + * + * Unlike [addMemberUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _addMemberUsers(): JsonField> = body._addMemberUsers() + + /** + * 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 [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 [removeMemberGroups]. + * + * Unlike [removeMemberGroups], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _removeMemberGroups(): JsonField> = body._removeMemberGroups() + + /** + * Returns the raw JSON value of [removeMemberUsers]. + * + * Unlike [removeMemberUsers], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _removeMemberUsers(): JsonField> = body._removeMemberUsers() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -66,361 +150,734 @@ constructor( } } - @JsonDeserialize(builder = GroupUpdateBody.Builder::class) @NoAutoDetect - class GroupUpdateBody - internal constructor( - private val addMemberGroups: List?, - private val addMemberUsers: List?, - private val description: String?, - private val name: String?, - private val removeMemberGroups: List?, - private val removeMemberUsers: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("add_member_groups") + @ExcludeMissing + private val addMemberGroups: JsonField> = JsonMissing.of(), + @JsonProperty("add_member_users") + @ExcludeMissing + private val addMemberUsers: JsonField> = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("remove_member_groups") + @ExcludeMissing + private val removeMemberGroups: JsonField> = JsonMissing.of(), + @JsonProperty("remove_member_users") + @ExcludeMissing + private val removeMemberUsers: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of group IDs to add to the group's inheriting-from set */ - @JsonProperty("add_member_groups") fun addMemberGroups(): List? = addMemberGroups - - /** A list of user IDs to add to the group */ - @JsonProperty("add_member_users") fun addMemberUsers(): List? = addMemberUsers - - /** Textual description of the group */ - @JsonProperty("description") fun description(): String? = description - - /** Name of the group */ - @JsonProperty("name") fun name(): String? = name - - /** A list of group IDs to remove from the group's inheriting-from set */ + /** + * A list of group IDs to add to the group's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun addMemberGroups(): Optional> = + Optional.ofNullable(addMemberGroups.getNullable("add_member_groups")) + + /** + * A list of user IDs to add to the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun addMemberUsers(): Optional> = + Optional.ofNullable(addMemberUsers.getNullable("add_member_users")) + + /** + * Textual description of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * A list of group IDs to remove from the group's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeMemberGroups(): Optional> = + Optional.ofNullable(removeMemberGroups.getNullable("remove_member_groups")) + + /** + * A list of user IDs to remove from the group + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeMemberUsers(): Optional> = + Optional.ofNullable(removeMemberUsers.getNullable("remove_member_users")) + + /** + * Returns the raw JSON value of [addMemberGroups]. + * + * Unlike [addMemberGroups], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("add_member_groups") + @ExcludeMissing + fun _addMemberGroups(): JsonField> = addMemberGroups + + /** + * Returns the raw JSON value of [addMemberUsers]. + * + * Unlike [addMemberUsers], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("add_member_users") + @ExcludeMissing + fun _addMemberUsers(): JsonField> = addMemberUsers + + /** + * 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 [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 [removeMemberGroups]. + * + * Unlike [removeMemberGroups], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("remove_member_groups") - fun removeMemberGroups(): List? = removeMemberGroups - - /** A list of user IDs to remove from the group */ + @ExcludeMissing + fun _removeMemberGroups(): JsonField> = removeMemberGroups + + /** + * Returns the raw JSON value of [removeMemberUsers]. + * + * Unlike [removeMemberUsers], this method doesn't throw if the JSON field has an unexpected + * type. + */ @JsonProperty("remove_member_users") - fun removeMemberUsers(): List? = removeMemberUsers + @ExcludeMissing + fun _removeMemberUsers(): JsonField> = removeMemberUsers @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is GroupUpdateBody && - this.addMemberGroups == other.addMemberGroups && - this.addMemberUsers == other.addMemberUsers && - this.description == other.description && - this.name == other.name && - this.removeMemberGroups == other.removeMemberGroups && - this.removeMemberUsers == other.removeMemberUsers && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - addMemberGroups, - addMemberUsers, - description, - name, - removeMemberGroups, - removeMemberUsers, - additionalProperties, - ) - } - return hashCode + addMemberGroups() + addMemberUsers() + description() + name() + removeMemberGroups() + removeMemberUsers() + validated = true } - override fun toString() = - "GroupUpdateBody{addMemberGroups=$addMemberGroups, addMemberUsers=$addMemberUsers, description=$description, name=$name, removeMemberGroups=$removeMemberGroups, removeMemberUsers=$removeMemberUsers, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var addMemberGroups: List? = null - private var addMemberUsers: List? = null - private var description: String? = null - private var name: String? = null - private var removeMemberGroups: List? = null - private var removeMemberUsers: List? = null + private var addMemberGroups: JsonField>? = null + private var addMemberUsers: JsonField>? = null + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var removeMemberGroups: JsonField>? = null + private var removeMemberUsers: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(groupUpdateBody: GroupUpdateBody) = apply { - this.addMemberGroups = groupUpdateBody.addMemberGroups - this.addMemberUsers = groupUpdateBody.addMemberUsers - this.description = groupUpdateBody.description - this.name = groupUpdateBody.name - this.removeMemberGroups = groupUpdateBody.removeMemberGroups - this.removeMemberUsers = groupUpdateBody.removeMemberUsers - additionalProperties(groupUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + addMemberGroups = body.addMemberGroups.map { it.toMutableList() } + addMemberUsers = body.addMemberUsers.map { it.toMutableList() } + description = body.description + name = body.name + removeMemberGroups = body.removeMemberGroups.map { it.toMutableList() } + removeMemberUsers = body.removeMemberUsers.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of group IDs to add to the group's inheriting-from set */ - @JsonProperty("add_member_groups") - fun addMemberGroups(addMemberGroups: List) = apply { - this.addMemberGroups = addMemberGroups + fun addMemberGroups(addMemberGroups: List?) = + addMemberGroups(JsonField.ofNullable(addMemberGroups)) + + /** Alias for calling [Builder.addMemberGroups] with `addMemberGroups.orElse(null)`. */ + fun addMemberGroups(addMemberGroups: Optional>) = + addMemberGroups(addMemberGroups.getOrNull()) + + /** + * Sets [Builder.addMemberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberGroups] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun addMemberGroups(addMemberGroups: JsonField>) = apply { + this.addMemberGroups = addMemberGroups.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [addMemberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberGroup(addMemberGroup: String) = apply { + addMemberGroups = + (addMemberGroups ?: JsonField.of(mutableListOf())).also { + checkKnown("addMemberGroups", it).add(addMemberGroup) + } } /** A list of user IDs to add to the group */ - @JsonProperty("add_member_users") - fun addMemberUsers(addMemberUsers: List) = apply { - this.addMemberUsers = addMemberUsers + fun addMemberUsers(addMemberUsers: List?) = + addMemberUsers(JsonField.ofNullable(addMemberUsers)) + + /** Alias for calling [Builder.addMemberUsers] with `addMemberUsers.orElse(null)`. */ + fun addMemberUsers(addMemberUsers: Optional>) = + addMemberUsers(addMemberUsers.getOrNull()) + + /** + * Sets [Builder.addMemberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberUsers] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun addMemberUsers(addMemberUsers: JsonField>) = apply { + this.addMemberUsers = addMemberUsers.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [addMemberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberUser(addMemberUser: String) = apply { + addMemberUsers = + (addMemberUsers ?: JsonField.of(mutableListOf())).also { + checkKnown("addMemberUsers", it).add(addMemberUser) + } } /** Textual description of the group */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** Name of the group */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 list of group IDs to remove from the group's inheriting-from set */ - @JsonProperty("remove_member_groups") - fun removeMemberGroups(removeMemberGroups: List) = apply { - this.removeMemberGroups = removeMemberGroups + fun removeMemberGroups(removeMemberGroups: List?) = + removeMemberGroups(JsonField.ofNullable(removeMemberGroups)) + + /** + * Alias for calling [Builder.removeMemberGroups] with + * `removeMemberGroups.orElse(null)`. + */ + fun removeMemberGroups(removeMemberGroups: Optional>) = + removeMemberGroups(removeMemberGroups.getOrNull()) + + /** + * Sets [Builder.removeMemberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberGroups] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun removeMemberGroups(removeMemberGroups: JsonField>) = apply { + this.removeMemberGroups = removeMemberGroups.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [removeMemberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberGroup(removeMemberGroup: String) = apply { + removeMemberGroups = + (removeMemberGroups ?: JsonField.of(mutableListOf())).also { + checkKnown("removeMemberGroups", it).add(removeMemberGroup) + } } /** A list of user IDs to remove from the group */ - @JsonProperty("remove_member_users") - fun removeMemberUsers(removeMemberUsers: List) = apply { - this.removeMemberUsers = removeMemberUsers + fun removeMemberUsers(removeMemberUsers: List?) = + removeMemberUsers(JsonField.ofNullable(removeMemberUsers)) + + /** + * Alias for calling [Builder.removeMemberUsers] with `removeMemberUsers.orElse(null)`. + */ + fun removeMemberUsers(removeMemberUsers: Optional>) = + removeMemberUsers(removeMemberUsers.getOrNull()) + + /** + * Sets [Builder.removeMemberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberUsers] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun removeMemberUsers(removeMemberUsers: JsonField>) = apply { + this.removeMemberUsers = removeMemberUsers.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [removeMemberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberUser(removeMemberUser: String) = apply { + removeMemberUsers = + (removeMemberUsers ?: JsonField.of(mutableListOf())).also { + checkKnown("removeMemberUsers", it).add(removeMemberUser) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): GroupUpdateBody = - GroupUpdateBody( - addMemberGroups?.toUnmodifiable(), - addMemberUsers?.toUnmodifiable(), + 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. + */ + fun build(): Body = + Body( + (addMemberGroups ?: JsonMissing.of()).map { it.toImmutable() }, + (addMemberUsers ?: JsonMissing.of()).map { it.toImmutable() }, description, name, - removeMemberGroups?.toUnmodifiable(), - removeMemberUsers?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (removeMemberGroups ?: JsonMissing.of()).map { it.toImmutable() }, + (removeMemberUsers ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && addMemberGroups == other.addMemberGroups && addMemberUsers == other.addMemberUsers && description == other.description && name == other.name && removeMemberGroups == other.removeMemberGroups && removeMemberUsers == other.removeMemberUsers && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is GroupUpdateParams && - this.groupId == other.groupId && - this.addMemberGroups == other.addMemberGroups && - this.addMemberUsers == other.addMemberUsers && - this.description == other.description && - this.name == other.name && - this.removeMemberGroups == other.removeMemberGroups && - this.removeMemberUsers == other.removeMemberUsers && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(addMemberGroups, addMemberUsers, description, name, removeMemberGroups, removeMemberUsers, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - groupId, - addMemberGroups, - addMemberUsers, - description, - name, - removeMemberGroups, - removeMemberUsers, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "GroupUpdateParams{groupId=$groupId, addMemberGroups=$addMemberGroups, addMemberUsers=$addMemberUsers, description=$description, name=$name, removeMemberGroups=$removeMemberGroups, removeMemberUsers=$removeMemberUsers, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{addMemberGroups=$addMemberGroups, addMemberUsers=$addMemberUsers, description=$description, name=$name, removeMemberGroups=$removeMemberGroups, removeMemberUsers=$removeMemberUsers, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [GroupUpdateParams]. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [GroupUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var groupId: String? = null - private var addMemberGroups: MutableList = mutableListOf() - private var addMemberUsers: MutableList = mutableListOf() - private var description: String? = null - private var name: String? = null - private var removeMemberGroups: MutableList = mutableListOf() - private var removeMemberUsers: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(groupUpdateParams: GroupUpdateParams) = apply { - this.groupId = groupUpdateParams.groupId - this.addMemberGroups(groupUpdateParams.addMemberGroups ?: listOf()) - this.addMemberUsers(groupUpdateParams.addMemberUsers ?: listOf()) - this.description = groupUpdateParams.description - this.name = groupUpdateParams.name - this.removeMemberGroups(groupUpdateParams.removeMemberGroups ?: listOf()) - this.removeMemberUsers(groupUpdateParams.removeMemberUsers ?: listOf()) - additionalQueryParams(groupUpdateParams.additionalQueryParams) - additionalHeaders(groupUpdateParams.additionalHeaders) - additionalBodyProperties(groupUpdateParams.additionalBodyProperties) + groupId = groupUpdateParams.groupId + body = groupUpdateParams.body.toBuilder() + additionalHeaders = groupUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = groupUpdateParams.additionalQueryParams.toBuilder() } /** Group id */ fun groupId(groupId: String) = apply { this.groupId = groupId } /** A list of group IDs to add to the group's inheriting-from set */ - fun addMemberGroups(addMemberGroups: List) = apply { - this.addMemberGroups.clear() - this.addMemberGroups.addAll(addMemberGroups) + fun addMemberGroups(addMemberGroups: List?) = apply { + body.addMemberGroups(addMemberGroups) } - /** A list of group IDs to add to the group's inheriting-from set */ + /** Alias for calling [Builder.addMemberGroups] with `addMemberGroups.orElse(null)`. */ + fun addMemberGroups(addMemberGroups: Optional>) = + addMemberGroups(addMemberGroups.getOrNull()) + + /** + * Sets [Builder.addMemberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberGroups] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun addMemberGroups(addMemberGroups: JsonField>) = apply { + body.addMemberGroups(addMemberGroups) + } + + /** + * Adds a single [String] to [addMemberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addAddMemberGroup(addMemberGroup: String) = apply { - this.addMemberGroups.add(addMemberGroup) + body.addAddMemberGroup(addMemberGroup) } /** A list of user IDs to add to the group */ - fun addMemberUsers(addMemberUsers: List) = apply { - this.addMemberUsers.clear() - this.addMemberUsers.addAll(addMemberUsers) + fun addMemberUsers(addMemberUsers: List?) = apply { + body.addMemberUsers(addMemberUsers) } - /** A list of user IDs to add to the group */ - fun addAddMemberUser(addMemberUser: String) = apply { - this.addMemberUsers.add(addMemberUser) + /** Alias for calling [Builder.addMemberUsers] with `addMemberUsers.orElse(null)`. */ + fun addMemberUsers(addMemberUsers: Optional>) = + addMemberUsers(addMemberUsers.getOrNull()) + + /** + * Sets [Builder.addMemberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberUsers] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun addMemberUsers(addMemberUsers: JsonField>) = apply { + body.addMemberUsers(addMemberUsers) } + /** + * Adds a single [String] to [addMemberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberUser(addMemberUser: String) = apply { body.addAddMemberUser(addMemberUser) } + /** Textual description of the group */ - fun description(description: String) = apply { this.description = description } + 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) } /** Name of the group */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 list of group IDs to remove from the group's inheriting-from set */ - fun removeMemberGroups(removeMemberGroups: List) = apply { - this.removeMemberGroups.clear() - this.removeMemberGroups.addAll(removeMemberGroups) + fun removeMemberGroups(removeMemberGroups: List?) = apply { + body.removeMemberGroups(removeMemberGroups) } - /** A list of group IDs to remove from the group's inheriting-from set */ + /** + * Alias for calling [Builder.removeMemberGroups] with `removeMemberGroups.orElse(null)`. + */ + fun removeMemberGroups(removeMemberGroups: Optional>) = + removeMemberGroups(removeMemberGroups.getOrNull()) + + /** + * Sets [Builder.removeMemberGroups] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberGroups] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun removeMemberGroups(removeMemberGroups: JsonField>) = apply { + body.removeMemberGroups(removeMemberGroups) + } + + /** + * Adds a single [String] to [removeMemberGroups]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addRemoveMemberGroup(removeMemberGroup: String) = apply { - this.removeMemberGroups.add(removeMemberGroup) + body.addRemoveMemberGroup(removeMemberGroup) } /** A list of user IDs to remove from the group */ - fun removeMemberUsers(removeMemberUsers: List) = apply { - this.removeMemberUsers.clear() - this.removeMemberUsers.addAll(removeMemberUsers) + fun removeMemberUsers(removeMemberUsers: List?) = apply { + body.removeMemberUsers(removeMemberUsers) } - /** A list of user IDs to remove from the group */ - fun addRemoveMemberUser(removeMemberUser: String) = apply { - this.removeMemberUsers.add(removeMemberUser) + /** Alias for calling [Builder.removeMemberUsers] with `removeMemberUsers.orElse(null)`. */ + fun removeMemberUsers(removeMemberUsers: Optional>) = + removeMemberUsers(removeMemberUsers.getOrNull()) + + /** + * Sets [Builder.removeMemberUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberUsers] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun removeMemberUsers(removeMemberUsers: JsonField>) = apply { + body.removeMemberUsers(removeMemberUsers) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** + * Adds a single [String] to [removeMemberUsers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberUser(removeMemberUser: String) = apply { + body.addRemoveMemberUser(removeMemberUser) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [GroupUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .groupId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): GroupUpdateParams = GroupUpdateParams( - checkNotNull(groupId) { "`groupId` is required but was not set" }, - if (addMemberGroups.size == 0) null else addMemberGroups.toUnmodifiable(), - if (addMemberUsers.size == 0) null else addMemberUsers.toUnmodifiable(), - description, - name, - if (removeMemberGroups.size == 0) null else removeMemberGroups.toUnmodifiable(), - if (removeMemberUsers.size == 0) null else removeMemberUsers.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("groupId", groupId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GroupUpdateParams && groupId == other.groupId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(groupId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "GroupUpdateParams{groupId=$groupId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEvent.kt new file mode 100644 index 00000000..abeb2f43 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEvent.kt @@ -0,0 +1,952 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.time.OffsetDateTime +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A dataset event */ +@NoAutoDetect +class InsertDatasetEvent +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_is_merge") + @ExcludeMissing + private val _isMerge: JsonField = JsonMissing.of(), + @JsonProperty("_merge_paths") + @ExcludeMissing + private val _mergePaths: JsonField>> = JsonMissing.of(), + @JsonProperty("_object_delete") + @ExcludeMissing + private val _objectDelete: JsonField = JsonMissing.of(), + @JsonProperty("_parent_id") + @ExcludeMissing + private val _parentId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("span_parents") + @ExcludeMissing + private val spanParents: JsonField> = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate + * one for you + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = Optional.ofNullable(id.getNullable("id")) + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same id + * in the DB. By default (or when set to `false`), the existing row is completely replaced by + * the new row. When set to `true`, the new row is deep-merged into the existing row, if one is + * found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when `_is_merge=true`. + * `_merge_paths` is a list of paths, where each path is a list of field names. The deep merge + * will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, + * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, + * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, + * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": + * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the + * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and + * `input.c`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _mergePaths(): Optional>> = + Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) + + /** + * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not show up + * in subsequent fetches for this dataset + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _objectDelete(): Optional = + Optional.ofNullable(_objectDelete.getNullable("_object_delete")) + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent + * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after + * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row + * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this + * case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) + + /** + * The timestamp the dataset event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * The output of your application, including post-processing (an arbitrary, JSON serializable + * object) + */ + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected + + /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rootSpanId(): Optional = Optional.ofNullable(rootSpanId.getNullable("root_span_id")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanId(): Optional = Optional.ofNullable(spanId.getNullable("span_id")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanParents(): Optional> = + Optional.ofNullable(spanParents.getNullable("span_parents")) + + /** + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + + /** + * 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 [_isMerge]. + * + * Unlike [_isMerge], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge(): JsonField = _isMerge + + /** + * Returns the raw JSON value of [_mergePaths]. + * + * Unlike [_mergePaths], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_merge_paths") + @ExcludeMissing + fun __mergePaths(): JsonField>> = _mergePaths + + /** + * Returns the raw JSON value of [_objectDelete]. + * + * Unlike [_objectDelete], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_object_delete") + @ExcludeMissing + fun __objectDelete(): JsonField = _objectDelete + + /** + * Returns the raw JSON value of [_parentId]. + * + * Unlike [_parentId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_parent_id") @ExcludeMissing fun __parentId(): JsonField = _parentId + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId + + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId + + /** + * Returns the raw JSON value of [spanParents]. + * + * Unlike [spanParents], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_parents") + @ExcludeMissing + fun _spanParents(): JsonField> = spanParents + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InsertDatasetEvent = apply { + if (validated) { + return@apply + } + + id() + _isMerge() + _mergePaths() + _objectDelete() + _parentId() + created() + metadata().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + rootSpanId() + spanId() + spanParents() + tags() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [InsertDatasetEvent]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InsertDatasetEvent]. */ + class Builder internal constructor() { + + private var id: JsonField = JsonMissing.of() + private var _isMerge: JsonField = JsonMissing.of() + private var _mergePaths: JsonField>>? = null + private var _objectDelete: JsonField = JsonMissing.of() + private var _parentId: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var rootSpanId: JsonField = JsonMissing.of() + private var spanId: JsonField = JsonMissing.of() + private var spanParents: JsonField>? = null + private var tags: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insertDatasetEvent: InsertDatasetEvent) = apply { + id = insertDatasetEvent.id + _isMerge = insertDatasetEvent._isMerge + _mergePaths = insertDatasetEvent._mergePaths.map { it.toMutableList() } + _objectDelete = insertDatasetEvent._objectDelete + _parentId = insertDatasetEvent._parentId + created = insertDatasetEvent.created + expected = insertDatasetEvent.expected + input = insertDatasetEvent.input + metadata = insertDatasetEvent.metadata + origin = insertDatasetEvent.origin + rootSpanId = insertDatasetEvent.rootSpanId + spanId = insertDatasetEvent.spanId + spanParents = insertDatasetEvent.spanParents.map { it.toMutableList() } + tags = insertDatasetEvent.tags.map { it.toMutableList() } + additionalProperties = insertDatasetEvent.additionalProperties.toMutableMap() + } + + /** + * A unique identifier for the dataset event. If you don't provide one, BrainTrust will + * generate one for you + */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * 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 } + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same + * id in the DB. By default (or when set to `false`), the existing row is completely + * replaced by the new row. When set to `true`, the new row is deep-merged into the existing + * row, if one is found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + */ + fun _isMerge(_isMerge: Boolean?) = _isMerge(JsonField.ofNullable(_isMerge)) + + /** + * Alias for [Builder._isMerge]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _isMerge(_isMerge: Boolean) = _isMerge(_isMerge as Boolean?) + + /** Alias for calling [Builder._isMerge] with `_isMerge.orElse(null)`. */ + fun _isMerge(_isMerge: Optional) = _isMerge(_isMerge.getOrNull()) + + /** + * Sets [Builder._isMerge] to an arbitrary JSON value. + * + * You should usually call [Builder._isMerge] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when + * `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of field + * names. The deep merge will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": + * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": + * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": + * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": + * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this + * case, due to the merge paths, we have replaced `input.a` and `output`, but have still + * deep-merged `input` and `input.c`. + */ + fun _mergePaths(_mergePaths: List>?) = + _mergePaths(JsonField.ofNullable(_mergePaths)) + + /** Alias for calling [Builder._mergePaths] with `_mergePaths.orElse(null)`. */ + fun _mergePaths(_mergePaths: Optional>>) = + _mergePaths(_mergePaths.getOrNull()) + + /** + * Sets [Builder._mergePaths] to an arbitrary JSON value. + * + * You should usually call [Builder._mergePaths] with a well-typed `List>` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun _mergePaths(_mergePaths: JsonField>>) = apply { + this._mergePaths = _mergePaths.map { it.toMutableList() } + } + + /** + * Adds a single [List] to [_mergePaths]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMergePath(mergePath: List) = apply { + _mergePaths = + (_mergePaths ?: JsonField.of(mutableListOf())).also { + checkKnown("_mergePaths", it).add(mergePath) + } + } + + /** + * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not + * show up in subsequent fetches for this dataset + */ + fun _objectDelete(_objectDelete: Boolean?) = + _objectDelete(JsonField.ofNullable(_objectDelete)) + + /** + * Alias for [Builder._objectDelete]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _objectDelete(_objectDelete: Boolean) = _objectDelete(_objectDelete as Boolean?) + + /** Alias for calling [Builder._objectDelete] with `_objectDelete.orElse(null)`. */ + fun _objectDelete(_objectDelete: Optional) = + _objectDelete(_objectDelete.getOrNull()) + + /** + * Sets [Builder._objectDelete] to an arbitrary JSON value. + * + * You should usually call [Builder._objectDelete] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun _objectDelete(_objectDelete: JsonField) = apply { + this._objectDelete = _objectDelete + } + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the + * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the + * root span row `"abc"` will show up in the summary view. You can view the full trace + * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun _parentId(_parentId: String?) = _parentId(JsonField.ofNullable(_parentId)) + + /** Alias for calling [Builder._parentId] with `_parentId.orElse(null)`. */ + fun _parentId(_parentId: Optional) = _parentId(_parentId.getOrNull()) + + /** + * Sets [Builder._parentId] to an arbitrary JSON value. + * + * You should usually call [Builder._parentId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } + + /** The timestamp the dataset event was created */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** + * The output of your application, including post-processing (an arbitrary, JSON + * serializable object) + */ + fun expected(expected: JsonValue) = apply { this.expected = expected } + + /** + * The argument that uniquely define an input case (an arbitrary, JSON serializable object) + */ + fun input(input: JsonValue) = apply { this.input = input } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. + * For example, you could log the `prompt`, example's `id`, or anything else that would be + * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, + * but its keys must be strings + */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun rootSpanId(rootSpanId: String?) = rootSpanId(JsonField.ofNullable(rootSpanId)) + + /** Alias for calling [Builder.rootSpanId] with `rootSpanId.orElse(null)`. */ + fun rootSpanId(rootSpanId: Optional) = rootSpanId(rootSpanId.getOrNull()) + + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanId(spanId: String?) = spanId(JsonField.ofNullable(spanId)) + + /** Alias for calling [Builder.spanId] with `spanId.orElse(null)`. */ + fun spanId(spanId: Optional) = spanId(spanId.getOrNull()) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanParents(spanParents: List?) = spanParents(JsonField.ofNullable(spanParents)) + + /** Alias for calling [Builder.spanParents] with `spanParents.orElse(null)`. */ + fun spanParents(spanParents: Optional>) = spanParents(spanParents.getOrNull()) + + /** + * Sets [Builder.spanParents] to an arbitrary JSON value. + * + * You should usually call [Builder.spanParents] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun spanParents(spanParents: JsonField>) = apply { + this.spanParents = spanParents.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [spanParents]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanParent(spanParent: String) = apply { + spanParents = + (spanParents ?: JsonField.of(mutableListOf())).also { + checkKnown("spanParents", it).add(spanParent) + } + } + + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 [InsertDatasetEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InsertDatasetEvent = + InsertDatasetEvent( + id, + _isMerge, + (_mergePaths ?: JsonMissing.of()).map { it.toImmutable() }, + _objectDelete, + _parentId, + created, + expected, + input, + metadata, + origin, + rootSpanId, + spanId, + (spanParents ?: JsonMissing.of()).map { it.toImmutable() }, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + */ + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + model() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InsertDatasetEvent && id == other.id && _isMerge == other._isMerge && _mergePaths == other._mergePaths && _objectDelete == other._objectDelete && _parentId == other._parentId && created == other.created && expected == other.expected && input == other.input && metadata == other.metadata && origin == other.origin && rootSpanId == other.rootSpanId && spanId == other.spanId && spanParents == other.spanParents && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _isMerge, _mergePaths, _objectDelete, _parentId, created, expected, input, metadata, origin, rootSpanId, spanId, spanParents, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InsertDatasetEvent{id=$id, _isMerge=$_isMerge, _mergePaths=$_mergePaths, _objectDelete=$_objectDelete, _parentId=$_parentId, created=$created, expected=$expected, input=$input, metadata=$metadata, origin=$origin, rootSpanId=$rootSpanId, spanId=$spanId, spanParents=$spanParents, tags=$tags, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventMerge.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventMerge.kt deleted file mode 100755 index 5e2fade0..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventMerge.kt +++ /dev/null @@ -1,514 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertDatasetEventMerge.Builder::class) -@NoAutoDetect -class InsertDatasetEventMerge -private constructor( - private val input: JsonValue, - private val expected: JsonValue, - private val metadata: JsonField, - private val tags: JsonField>, - private val id: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _mergePaths: JsonField>>, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object) - */ - fun expected(): JsonValue = expected - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate - * one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** The timestamp the dataset event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not show up - * in subsequent fetches for this dataset - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Boolean = _isMerge.getRequired("_is_merge") - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - fun _mergePaths(): Optional>> = - Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) - - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object) - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate - * one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The timestamp the dataset event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not show up - * in subsequent fetches for this dataset - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - @JsonProperty("_merge_paths") @ExcludeMissing fun __mergePaths() = _mergePaths - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertDatasetEventMerge = apply { - if (!validated) { - input() - expected() - metadata().map { it.validate() } - tags() - id() - created() - _objectDelete() - _isMerge() - _mergePaths() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertDatasetEventMerge && - this.input == other.input && - this.expected == other.expected && - this.metadata == other.metadata && - this.tags == other.tags && - this.id == other.id && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._mergePaths == other._mergePaths && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - expected, - metadata, - tags, - id, - created, - _objectDelete, - _isMerge, - _mergePaths, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertDatasetEventMerge{input=$input, expected=$expected, metadata=$metadata, tags=$tags, id=$id, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _mergePaths=$_mergePaths, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _mergePaths: JsonField>> = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertDatasetEventMerge: InsertDatasetEventMerge) = apply { - this.input = insertDatasetEventMerge.input - this.expected = insertDatasetEventMerge.expected - this.metadata = insertDatasetEventMerge.metadata - this.tags = insertDatasetEventMerge.tags - this.id = insertDatasetEventMerge.id - this.created = insertDatasetEventMerge.created - this._objectDelete = insertDatasetEventMerge._objectDelete - this._isMerge = insertDatasetEventMerge._isMerge - this._mergePaths = insertDatasetEventMerge._mergePaths - additionalProperties(insertDatasetEventMerge.additionalProperties) - } - - /** - * The argument that uniquely define an input case (an arbitrary, JSON serializable object) - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object) - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** The timestamp the dataset event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the dataset event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not - * show up in subsequent fetches for this dataset - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not - * show up in subsequent fetches for this dataset - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - fun _mergePaths(_mergePaths: List>) = _mergePaths(JsonField.of(_mergePaths)) - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - @JsonProperty("_merge_paths") - @ExcludeMissing - fun _mergePaths(_mergePaths: JsonField>>) = apply { - this._mergePaths = _mergePaths - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertDatasetEventMerge = - InsertDatasetEventMerge( - input, - expected, - metadata, - tags.map { it.toUnmodifiable() }, - id, - created, - _objectDelete, - _isMerge, - _mergePaths.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplace.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplace.kt deleted file mode 100755 index 2d77d5bd..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplace.kt +++ /dev/null @@ -1,507 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertDatasetEventReplace.Builder::class) -@NoAutoDetect -class InsertDatasetEventReplace -private constructor( - private val input: JsonValue, - private val expected: JsonValue, - private val metadata: JsonField, - private val tags: JsonField>, - private val id: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _parentId: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object) - */ - fun expected(): JsonValue = expected - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate - * one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** The timestamp the dataset event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not show up - * in subsequent fetches for this dataset - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) - - /** The argument that uniquely define an input case (an arbitrary, JSON serializable object) */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object) - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will generate - * one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The timestamp the dataset event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not show up - * in subsequent fetches for this dataset - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") @ExcludeMissing fun __parentId() = _parentId - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertDatasetEventReplace = apply { - if (!validated) { - input() - expected() - metadata().map { it.validate() } - tags() - id() - created() - _objectDelete() - _isMerge() - _parentId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertDatasetEventReplace && - this.input == other.input && - this.expected == other.expected && - this.metadata == other.metadata && - this.tags == other.tags && - this.id == other.id && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._parentId == other._parentId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - expected, - metadata, - tags, - id, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertDatasetEventReplace{input=$input, expected=$expected, metadata=$metadata, tags=$tags, id=$id, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _parentId=$_parentId, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _parentId: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertDatasetEventReplace: InsertDatasetEventReplace) = apply { - this.input = insertDatasetEventReplace.input - this.expected = insertDatasetEventReplace.expected - this.metadata = insertDatasetEventReplace.metadata - this.tags = insertDatasetEventReplace.tags - this.id = insertDatasetEventReplace.id - this.created = insertDatasetEventReplace.created - this._objectDelete = insertDatasetEventReplace._objectDelete - this._isMerge = insertDatasetEventReplace._isMerge - this._parentId = insertDatasetEventReplace._parentId - additionalProperties(insertDatasetEventReplace.additionalProperties) - } - - /** - * The argument that uniquely define an input case (an arbitrary, JSON serializable object) - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object) - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the dataset event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** The timestamp the dataset event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the dataset event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not - * show up in subsequent fetches for this dataset - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the dataset event deleted. Deleted events will not - * show up in subsequent fetches for this dataset - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(_parentId: String) = _parentId(JsonField.of(_parentId)) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") - @ExcludeMissing - fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertDatasetEventReplace = - InsertDatasetEventReplace( - input, - expected, - metadata, - tags.map { it.toUnmodifiable() }, - id, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertEventsResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertEventsResponse.kt index 6646cb3e..8d756030 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertEventsResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertEventsResponse.kt @@ -7,82 +7,82 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects -@JsonDeserialize(builder = InsertEventsResponse.Builder::class) @NoAutoDetect class InsertEventsResponse +@JsonCreator private constructor( - private val rowIds: JsonField>, - private val additionalProperties: Map, + @JsonProperty("row_ids") + @ExcludeMissing + private val rowIds: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * The ids of all rows that were inserted, aligning one-to-one with the rows provided as input + * + * @throws BraintrustInvalidDataException 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 rowIds(): List = rowIds.getRequired("row_ids") /** - * The ids of all rows that were inserted, aligning one-to-one with the rows provided as input + * Returns the raw JSON value of [rowIds]. + * + * Unlike [rowIds], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("row_ids") @ExcludeMissing fun _rowIds() = rowIds + @JsonProperty("row_ids") @ExcludeMissing fun _rowIds(): JsonField> = rowIds @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): InsertEventsResponse = apply { - if (!validated) { - rowIds() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): InsertEventsResponse = apply { + if (validated) { + return@apply } - return other is InsertEventsResponse && - this.rowIds == other.rowIds && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(rowIds, additionalProperties) - } - return hashCode + rowIds() + validated = true } - override fun toString() = - "InsertEventsResponse{rowIds=$rowIds, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [InsertEventsResponse]. + * + * The following fields are required: + * ```java + * .rowIds() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InsertEventsResponse]. */ + class Builder internal constructor() { - private var rowIds: JsonField> = JsonMissing.of() + private var rowIds: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(insertEventsResponse: InsertEventsResponse) = apply { - this.rowIds = insertEventsResponse.rowIds - additionalProperties(insertEventsResponse.additionalProperties) + rowIds = insertEventsResponse.rowIds.map { it.toMutableList() } + additionalProperties = insertEventsResponse.additionalProperties.toMutableMap() } /** @@ -92,31 +92,80 @@ private constructor( fun rowIds(rowIds: List) = rowIds(JsonField.of(rowIds)) /** - * The ids of all rows that were inserted, aligning one-to-one with the rows provided as - * input + * Sets [Builder.rowIds] to an arbitrary JSON value. + * + * You should usually call [Builder.rowIds] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rowIds(rowIds: JsonField>) = apply { + this.rowIds = rowIds.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [rowIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. */ - @JsonProperty("row_ids") - @ExcludeMissing - fun rowIds(rowIds: JsonField>) = apply { this.rowIds = rowIds } + fun addRowId(rowId: String) = apply { + rowIds = + (rowIds ?: JsonField.of(mutableListOf())).also { + checkKnown("rowIds", it).add(rowId) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [InsertEventsResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .rowIds() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): InsertEventsResponse = InsertEventsResponse( - rowIds.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable() + checkRequired("rowIds", rowIds).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InsertEventsResponse && rowIds == other.rowIds && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(rowIds, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InsertEventsResponse{rowIds=$rowIds, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEvent.kt new file mode 100644 index 00000000..946c2f68 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEvent.kt @@ -0,0 +1,1895 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.time.OffsetDateTime +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** An experiment event */ +@NoAutoDetect +class InsertExperimentEvent +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_is_merge") + @ExcludeMissing + private val _isMerge: JsonField = JsonMissing.of(), + @JsonProperty("_merge_paths") + @ExcludeMissing + private val _mergePaths: JsonField>> = JsonMissing.of(), + @JsonProperty("_object_delete") + @ExcludeMissing + private val _objectDelete: JsonField = JsonMissing.of(), + @JsonProperty("_parent_id") + @ExcludeMissing + private val _parentId: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + private val context: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing private val error: JsonValue = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("metrics") + @ExcludeMissing + private val metrics: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("output") @ExcludeMissing private val output: JsonValue = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("span_attributes") + @ExcludeMissing + private val spanAttributes: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("span_parents") + @ExcludeMissing + private val spanParents: JsonField> = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * A unique identifier for the experiment event. If you don't provide one, BrainTrust will + * generate one for you + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = Optional.ofNullable(id.getNullable("id")) + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same id + * in the DB. By default (or when set to `false`), the existing row is completely replaced by + * the new row. When set to `true`, the new row is deep-merged into the existing row, if one is + * found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when `_is_merge=true`. + * `_merge_paths` is a list of paths, where each path is a list of field names. The deep merge + * will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, + * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, + * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, + * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": + * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the + * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and + * `input.c`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _mergePaths(): Optional>> = + Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) + + /** + * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not show + * up in subsequent fetches for this experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _objectDelete(): Optional = + Optional.ofNullable(_objectDelete.getNullable("_object_delete")) + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent + * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after + * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row + * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this + * case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) + + /** + * Context is additional information about the code that produced the experiment event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + + /** + * The timestamp the experiment event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** The error that occurred, if any. */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonValue = error + + /** + * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to + * `output` to determine if your `output` value is correct or not. Braintrust currently does not + * compare `output` to `expected` for you, since there are so many different ways to do that + * correctly. Instead, these values are just used to help you navigate your experiments while + * digging into analyses. However, we may later use these values to re-score outputs or + * fine-tune your models + */ + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected + + /** + * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). + * Later on, Braintrust will use the `input` to know whether two test cases are the same between + * experiments, so they should not contain experiment-specific state. A simple rule of thumb is + * that if you run the same experiment twice, the `input` should be identical + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * experiment event. Use "start" and "end" to track the time span over which the experiment + * event was produced + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) + + /** + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) + + /** + * The output of your application, including post-processing (an arbitrary, JSON serializable + * object), that allows you to determine whether the result is correct or not. For example, in + * an app that generates SQL queries, the `output` should be the _result_ of the SQL query + * generated by the model, not the query itself, because there may be multiple valid queries + * that answer a single question + */ + @JsonProperty("output") @ExcludeMissing fun _output(): JsonValue = output + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rootSpanId(): Optional = Optional.ofNullable(rootSpanId.getNullable("root_span_id")) + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare experiments + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + + /** + * Human-identifying attributes of the span, such as name, type, etc. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanAttributes(): Optional = + Optional.ofNullable(spanAttributes.getNullable("span_attributes")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanId(): Optional = Optional.ofNullable(spanId.getNullable("span_id")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanParents(): Optional> = + Optional.ofNullable(spanParents.getNullable("span_parents")) + + /** + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + + /** + * 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 [_isMerge]. + * + * Unlike [_isMerge], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge(): JsonField = _isMerge + + /** + * Returns the raw JSON value of [_mergePaths]. + * + * Unlike [_mergePaths], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_merge_paths") + @ExcludeMissing + fun __mergePaths(): JsonField>> = _mergePaths + + /** + * Returns the raw JSON value of [_objectDelete]. + * + * Unlike [_objectDelete], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_object_delete") + @ExcludeMissing + fun __objectDelete(): JsonField = _objectDelete + + /** + * Returns the raw JSON value of [_parentId]. + * + * Unlike [_parentId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_parent_id") @ExcludeMissing fun __parentId(): JsonField = _parentId + + /** + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [metrics]. + * + * Unlike [metrics], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metrics") @ExcludeMissing fun _metrics(): JsonField = metrics + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId + + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores + + /** + * Returns the raw JSON value of [spanAttributes]. + * + * Unlike [spanAttributes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_attributes") + @ExcludeMissing + fun _spanAttributes(): JsonField = spanAttributes + + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId + + /** + * Returns the raw JSON value of [spanParents]. + * + * Unlike [spanParents], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_parents") + @ExcludeMissing + fun _spanParents(): JsonField> = spanParents + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InsertExperimentEvent = apply { + if (validated) { + return@apply + } + + id() + _isMerge() + _mergePaths() + _objectDelete() + _parentId() + context().ifPresent { it.validate() } + created() + metadata().ifPresent { it.validate() } + metrics().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + rootSpanId() + scores().ifPresent { it.validate() } + spanAttributes().ifPresent { it.validate() } + spanId() + spanParents() + tags() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [InsertExperimentEvent]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InsertExperimentEvent]. */ + class Builder internal constructor() { + + private var id: JsonField = JsonMissing.of() + private var _isMerge: JsonField = JsonMissing.of() + private var _mergePaths: JsonField>>? = null + private var _objectDelete: JsonField = JsonMissing.of() + private var _parentId: JsonField = JsonMissing.of() + private var context: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() + private var error: JsonValue = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var metrics: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var output: JsonValue = JsonMissing.of() + private var rootSpanId: JsonField = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() + private var spanAttributes: JsonField = JsonMissing.of() + private var spanId: JsonField = JsonMissing.of() + private var spanParents: JsonField>? = null + private var tags: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insertExperimentEvent: InsertExperimentEvent) = apply { + id = insertExperimentEvent.id + _isMerge = insertExperimentEvent._isMerge + _mergePaths = insertExperimentEvent._mergePaths.map { it.toMutableList() } + _objectDelete = insertExperimentEvent._objectDelete + _parentId = insertExperimentEvent._parentId + context = insertExperimentEvent.context + created = insertExperimentEvent.created + error = insertExperimentEvent.error + expected = insertExperimentEvent.expected + input = insertExperimentEvent.input + metadata = insertExperimentEvent.metadata + metrics = insertExperimentEvent.metrics + origin = insertExperimentEvent.origin + output = insertExperimentEvent.output + rootSpanId = insertExperimentEvent.rootSpanId + scores = insertExperimentEvent.scores + spanAttributes = insertExperimentEvent.spanAttributes + spanId = insertExperimentEvent.spanId + spanParents = insertExperimentEvent.spanParents.map { it.toMutableList() } + tags = insertExperimentEvent.tags.map { it.toMutableList() } + additionalProperties = insertExperimentEvent.additionalProperties.toMutableMap() + } + + /** + * A unique identifier for the experiment event. If you don't provide one, BrainTrust will + * generate one for you + */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * 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 } + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same + * id in the DB. By default (or when set to `false`), the existing row is completely + * replaced by the new row. When set to `true`, the new row is deep-merged into the existing + * row, if one is found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + */ + fun _isMerge(_isMerge: Boolean?) = _isMerge(JsonField.ofNullable(_isMerge)) + + /** + * Alias for [Builder._isMerge]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _isMerge(_isMerge: Boolean) = _isMerge(_isMerge as Boolean?) + + /** Alias for calling [Builder._isMerge] with `_isMerge.orElse(null)`. */ + fun _isMerge(_isMerge: Optional) = _isMerge(_isMerge.getOrNull()) + + /** + * Sets [Builder._isMerge] to an arbitrary JSON value. + * + * You should usually call [Builder._isMerge] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when + * `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of field + * names. The deep merge will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": + * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": + * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": + * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": + * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this + * case, due to the merge paths, we have replaced `input.a` and `output`, but have still + * deep-merged `input` and `input.c`. + */ + fun _mergePaths(_mergePaths: List>?) = + _mergePaths(JsonField.ofNullable(_mergePaths)) + + /** Alias for calling [Builder._mergePaths] with `_mergePaths.orElse(null)`. */ + fun _mergePaths(_mergePaths: Optional>>) = + _mergePaths(_mergePaths.getOrNull()) + + /** + * Sets [Builder._mergePaths] to an arbitrary JSON value. + * + * You should usually call [Builder._mergePaths] with a well-typed `List>` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun _mergePaths(_mergePaths: JsonField>>) = apply { + this._mergePaths = _mergePaths.map { it.toMutableList() } + } + + /** + * Adds a single [List] to [_mergePaths]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMergePath(mergePath: List) = apply { + _mergePaths = + (_mergePaths ?: JsonField.of(mutableListOf())).also { + checkKnown("_mergePaths", it).add(mergePath) + } + } + + /** + * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not + * show up in subsequent fetches for this experiment + */ + fun _objectDelete(_objectDelete: Boolean?) = + _objectDelete(JsonField.ofNullable(_objectDelete)) + + /** + * Alias for [Builder._objectDelete]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _objectDelete(_objectDelete: Boolean) = _objectDelete(_objectDelete as Boolean?) + + /** Alias for calling [Builder._objectDelete] with `_objectDelete.orElse(null)`. */ + fun _objectDelete(_objectDelete: Optional) = + _objectDelete(_objectDelete.getOrNull()) + + /** + * Sets [Builder._objectDelete] to an arbitrary JSON value. + * + * You should usually call [Builder._objectDelete] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun _objectDelete(_objectDelete: JsonField) = apply { + this._objectDelete = _objectDelete + } + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the + * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the + * root span row `"abc"` will show up in the summary view. You can view the full trace + * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun _parentId(_parentId: String?) = _parentId(JsonField.ofNullable(_parentId)) + + /** Alias for calling [Builder._parentId] with `_parentId.orElse(null)`. */ + fun _parentId(_parentId: Optional) = _parentId(_parentId.getOrNull()) + + /** + * Sets [Builder._parentId] to an arbitrary JSON value. + * + * You should usually call [Builder._parentId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } + + /** + * Context is additional information about the code that produced the experiment event. It + * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to + * track the location in code which produced the experiment event + */ + fun context(context: Context?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [Context] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + /** The timestamp the experiment event was created */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** The error that occurred, if any. */ + fun error(error: JsonValue) = apply { this.error = error } + + /** + * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to + * `output` to determine if your `output` value is correct or not. Braintrust currently does + * not compare `output` to `expected` for you, since there are so many different ways to do + * that correctly. Instead, these values are just used to help you navigate your experiments + * while digging into analyses. However, we may later use these values to re-score outputs + * or fine-tune your models + */ + fun expected(expected: JsonValue) = apply { this.expected = expected } + + /** + * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). + * Later on, Braintrust will use the `input` to know whether two test cases are the same + * between experiments, so they should not contain experiment-specific state. A simple rule + * of thumb is that if you run the same experiment twice, the `input` should be identical + */ + fun input(input: JsonValue) = apply { this.input = input } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. + * For example, you could log the `prompt`, example's `id`, or anything else that would be + * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, + * but its keys must be strings + */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * experiment event. Use "start" and "end" to track the time span over which the experiment + * event was produced + */ + fun metrics(metrics: Metrics?) = metrics(JsonField.ofNullable(metrics)) + + /** Alias for calling [Builder.metrics] with `metrics.orElse(null)`. */ + fun metrics(metrics: Optional) = metrics(metrics.getOrNull()) + + /** + * Sets [Builder.metrics] to an arbitrary JSON value. + * + * You should usually call [Builder.metrics] with a well-typed [Metrics] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } + + /** + * The output of your application, including post-processing (an arbitrary, JSON + * serializable object), that allows you to determine whether the result is correct or not. + * For example, in an app that generates SQL queries, the `output` should be the _result_ of + * the SQL query generated by the model, not the query itself, because there may be multiple + * valid queries that answer a single question + */ + fun output(output: JsonValue) = apply { this.output = output } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun rootSpanId(rootSpanId: String?) = rootSpanId(JsonField.ofNullable(rootSpanId)) + + /** Alias for calling [Builder.rootSpanId] with `rootSpanId.orElse(null)`. */ + fun rootSpanId(rootSpanId: Optional) = rootSpanId(rootSpanId.getOrNull()) + + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a + * variety of signals that help you determine how accurate the outputs are compared to what + * you expect and diagnose failures. For example, a summarization app might have one score + * that tells you how accurate the summary is, and another that measures the word similarity + * between the generated and grouth truth summary. The word similarity score could help you + * determine whether the summarization was covering similar concepts or not. You can use + * these scores to help you sort, filter, and compare experiments + */ + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } + + /** Human-identifying attributes of the span, such as name, type, etc. */ + fun spanAttributes(spanAttributes: SpanAttributes?) = + spanAttributes(JsonField.ofNullable(spanAttributes)) + + /** Alias for calling [Builder.spanAttributes] with `spanAttributes.orElse(null)`. */ + fun spanAttributes(spanAttributes: Optional) = + spanAttributes(spanAttributes.getOrNull()) + + /** + * Sets [Builder.spanAttributes] to an arbitrary JSON value. + * + * You should usually call [Builder.spanAttributes] with a well-typed [SpanAttributes] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun spanAttributes(spanAttributes: JsonField) = apply { + this.spanAttributes = spanAttributes + } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanId(spanId: String?) = spanId(JsonField.ofNullable(spanId)) + + /** Alias for calling [Builder.spanId] with `spanId.orElse(null)`. */ + fun spanId(spanId: Optional) = spanId(spanId.getOrNull()) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanParents(spanParents: List?) = spanParents(JsonField.ofNullable(spanParents)) + + /** Alias for calling [Builder.spanParents] with `spanParents.orElse(null)`. */ + fun spanParents(spanParents: Optional>) = spanParents(spanParents.getOrNull()) + + /** + * Sets [Builder.spanParents] to an arbitrary JSON value. + * + * You should usually call [Builder.spanParents] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun spanParents(spanParents: JsonField>) = apply { + this.spanParents = spanParents.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [spanParents]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanParent(spanParent: String) = apply { + spanParents = + (spanParents ?: JsonField.of(mutableListOf())).also { + checkKnown("spanParents", it).add(spanParent) + } + } + + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 [InsertExperimentEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InsertExperimentEvent = + InsertExperimentEvent( + id, + _isMerge, + (_mergePaths ?: JsonMissing.of()).map { it.toImmutable() }, + _objectDelete, + _parentId, + context, + created, + error, + expected, + input, + metadata, + metrics, + origin, + output, + rootSpanId, + scores, + spanAttributes, + spanId, + (spanParents ?: JsonMissing.of()).map { it.toImmutable() }, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } + + /** + * Context is additional information about the code that produced the experiment event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the experiment event + */ + @NoAutoDetect + class Context + @JsonCreator + private constructor( + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonField = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonField = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * Name of the file in code where the experiment event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFilename(): Optional = + Optional.ofNullable(callerFilename.getNullable("caller_filename")) + + /** + * The function in code which created the experiment event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFunctionname(): Optional = + Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) + + /** + * Line of code where the experiment event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerLineno(): Optional = + Optional.ofNullable(callerLineno.getNullable("caller_lineno")) + + /** + * Returns the raw JSON value of [callerFilename]. + * + * Unlike [callerFilename], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonField = callerFilename + + /** + * Returns the raw JSON value of [callerFunctionname]. + * + * Unlike [callerFunctionname], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonField = callerFunctionname + + /** + * Returns the raw JSON value of [callerLineno]. + * + * Unlike [callerLineno], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_lineno") + @ExcludeMissing + fun _callerLineno(): JsonField = callerLineno + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Context = apply { + if (validated) { + return@apply + } + + callerFilename() + callerFunctionname() + callerLineno() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Context]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Context]. */ + class Builder internal constructor() { + + private var callerFilename: JsonField = JsonMissing.of() + private var callerFunctionname: JsonField = JsonMissing.of() + private var callerLineno: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(context: Context) = apply { + callerFilename = context.callerFilename + callerFunctionname = context.callerFunctionname + callerLineno = context.callerLineno + additionalProperties = context.additionalProperties.toMutableMap() + } + + /** Name of the file in code where the experiment event was created */ + fun callerFilename(callerFilename: String?) = + callerFilename(JsonField.ofNullable(callerFilename)) + + /** Alias for calling [Builder.callerFilename] with `callerFilename.orElse(null)`. */ + fun callerFilename(callerFilename: Optional) = + callerFilename(callerFilename.getOrNull()) + + /** + * Sets [Builder.callerFilename] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFilename] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFilename(callerFilename: JsonField) = apply { + this.callerFilename = callerFilename + } + + /** The function in code which created the experiment event */ + fun callerFunctionname(callerFunctionname: String?) = + callerFunctionname(JsonField.ofNullable(callerFunctionname)) + + /** + * Alias for calling [Builder.callerFunctionname] with + * `callerFunctionname.orElse(null)`. + */ + fun callerFunctionname(callerFunctionname: Optional) = + callerFunctionname(callerFunctionname.getOrNull()) + + /** + * Sets [Builder.callerFunctionname] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFunctionname] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFunctionname(callerFunctionname: JsonField) = apply { + this.callerFunctionname = callerFunctionname + } + + /** Line of code where the experiment event was created */ + fun callerLineno(callerLineno: Long?) = callerLineno(JsonField.ofNullable(callerLineno)) + + /** + * Alias for [Builder.callerLineno]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun callerLineno(callerLineno: Long) = callerLineno(callerLineno as Long?) + + /** Alias for calling [Builder.callerLineno] with `callerLineno.orElse(null)`. */ + fun callerLineno(callerLineno: Optional) = callerLineno(callerLineno.getOrNull()) + + /** + * Sets [Builder.callerLineno] to an arbitrary JSON value. + * + * You should usually call [Builder.callerLineno] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerLineno(callerLineno: JsonField) = apply { + this.callerLineno = callerLineno + } + + 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 [Context]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Context = + Context( + callerFilename, + callerFunctionname, + callerLineno, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Context && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Context{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" + } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + */ + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + model() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" + } + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * experiment event. Use "start" and "end" to track the time span over which the experiment + * event was produced + */ + @NoAutoDetect + class Metrics + @JsonCreator + private constructor( + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonValue = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonValue = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonValue = JsonMissing.of(), + @JsonProperty("completion_tokens") + @ExcludeMissing + private val completionTokens: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing private val end: JsonField = JsonMissing.of(), + @JsonProperty("prompt_tokens") + @ExcludeMissing + private val promptTokens: JsonField = JsonMissing.of(), + @JsonProperty("start") + @ExcludeMissing + private val start: JsonField = JsonMissing.of(), + @JsonProperty("tokens") + @ExcludeMissing + private val tokens: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** This metric is deprecated */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonValue = callerFilename + + /** This metric is deprecated */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonValue = callerFunctionname + + /** This metric is deprecated */ + @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno(): JsonValue = callerLineno + + /** + * The number of tokens in the completion generated by the model (only set if this is an LLM + * span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun completionTokens(): Optional = + Optional.ofNullable(completionTokens.getNullable("completion_tokens")) + + /** + * A unix timestamp recording when the section of code which produced the experiment event + * finished + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun end(): Optional = Optional.ofNullable(end.getNullable("end")) + + /** + * The number of tokens in the prompt used to generate the experiment event (only set if + * this is an LLM span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptTokens(): Optional = + Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) + + /** + * A unix timestamp recording when the section of code which produced the experiment event + * started + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun start(): Optional = Optional.ofNullable(start.getNullable("start")) + + /** + * The total number of tokens in the input and output of the experiment event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) + + /** + * Returns the raw JSON value of [completionTokens]. + * + * Unlike [completionTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("completion_tokens") + @ExcludeMissing + fun _completionTokens(): JsonField = completionTokens + + /** + * Returns the raw JSON value of [end]. + * + * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end + + /** + * Returns the raw JSON value of [promptTokens]. + * + * Unlike [promptTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("prompt_tokens") + @ExcludeMissing + fun _promptTokens(): JsonField = promptTokens + + /** + * Returns the raw JSON value of [start]. + * + * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start + + /** + * Returns the raw JSON value of [tokens]. + * + * Unlike [tokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tokens") @ExcludeMissing fun _tokens(): JsonField = tokens + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metrics = apply { + if (validated) { + return@apply + } + + completionTokens() + end() + promptTokens() + start() + tokens() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metrics]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metrics]. */ + class Builder internal constructor() { + + private var callerFilename: JsonValue = JsonMissing.of() + private var callerFunctionname: JsonValue = JsonMissing.of() + private var callerLineno: JsonValue = JsonMissing.of() + private var completionTokens: JsonField = JsonMissing.of() + private var end: JsonField = JsonMissing.of() + private var promptTokens: JsonField = JsonMissing.of() + private var start: JsonField = JsonMissing.of() + private var tokens: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metrics: Metrics) = apply { + callerFilename = metrics.callerFilename + callerFunctionname = metrics.callerFunctionname + callerLineno = metrics.callerLineno + completionTokens = metrics.completionTokens + end = metrics.end + promptTokens = metrics.promptTokens + start = metrics.start + tokens = metrics.tokens + additionalProperties = metrics.additionalProperties.toMutableMap() + } + + /** This metric is deprecated */ + fun callerFilename(callerFilename: JsonValue) = apply { + this.callerFilename = callerFilename + } + + /** This metric is deprecated */ + fun callerFunctionname(callerFunctionname: JsonValue) = apply { + this.callerFunctionname = callerFunctionname + } + + /** This metric is deprecated */ + fun callerLineno(callerLineno: JsonValue) = apply { this.callerLineno = callerLineno } + + /** + * The number of tokens in the completion generated by the model (only set if this is an + * LLM span) + */ + fun completionTokens(completionTokens: Long?) = + completionTokens(JsonField.ofNullable(completionTokens)) + + /** + * Alias for [Builder.completionTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun completionTokens(completionTokens: Long) = + completionTokens(completionTokens as Long?) + + /** + * Alias for calling [Builder.completionTokens] with `completionTokens.orElse(null)`. + */ + fun completionTokens(completionTokens: Optional) = + completionTokens(completionTokens.getOrNull()) + + /** + * Sets [Builder.completionTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.completionTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun completionTokens(completionTokens: JsonField) = apply { + this.completionTokens = completionTokens + } + + /** + * A unix timestamp recording when the section of code which produced the experiment + * event finished + */ + fun end(end: Double?) = end(JsonField.ofNullable(end)) + + /** + * Alias for [Builder.end]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun end(end: Double) = end(end as Double?) + + /** Alias for calling [Builder.end] with `end.orElse(null)`. */ + fun end(end: Optional) = end(end.getOrNull()) + + /** + * Sets [Builder.end] to an arbitrary JSON value. + * + * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun end(end: JsonField) = apply { this.end = end } + + /** + * The number of tokens in the prompt used to generate the experiment event (only set if + * this is an LLM span) + */ + fun promptTokens(promptTokens: Long?) = promptTokens(JsonField.ofNullable(promptTokens)) + + /** + * Alias for [Builder.promptTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun promptTokens(promptTokens: Long) = promptTokens(promptTokens as Long?) + + /** Alias for calling [Builder.promptTokens] with `promptTokens.orElse(null)`. */ + fun promptTokens(promptTokens: Optional) = promptTokens(promptTokens.getOrNull()) + + /** + * Sets [Builder.promptTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.promptTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptTokens(promptTokens: JsonField) = apply { + this.promptTokens = promptTokens + } + + /** + * A unix timestamp recording when the section of code which produced the experiment + * event started + */ + fun start(start: Double?) = start(JsonField.ofNullable(start)) + + /** + * Alias for [Builder.start]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun start(start: Double) = start(start as Double?) + + /** Alias for calling [Builder.start] with `start.orElse(null)`. */ + fun start(start: Optional) = start(start.getOrNull()) + + /** + * Sets [Builder.start] to an arbitrary JSON value. + * + * You should usually call [Builder.start] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun start(start: JsonField) = apply { this.start = start } + + /** The total number of tokens in the input and output of the experiment event. */ + fun tokens(tokens: Long?) = tokens(JsonField.ofNullable(tokens)) + + /** + * Alias for [Builder.tokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun tokens(tokens: Long) = tokens(tokens as Long?) + + /** Alias for calling [Builder.tokens] with `tokens.orElse(null)`. */ + fun tokens(tokens: Optional) = tokens(tokens.getOrNull()) + + /** + * Sets [Builder.tokens] to an arbitrary JSON value. + * + * You should usually call [Builder.tokens] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tokens(tokens: JsonField) = apply { this.tokens = tokens } + + 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 [Metrics]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metrics = + Metrics( + callerFilename, + callerFunctionname, + callerLineno, + completionTokens, + end, + promptTokens, + start, + tokens, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metrics && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && completionTokens == other.completionTokens && end == other.end && promptTokens == other.promptTokens && start == other.start && tokens == other.tokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, completionTokens, end, promptTokens, start, tokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metrics{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, completionTokens=$completionTokens, end=$end, promptTokens=$promptTokens, start=$start, tokens=$tokens, additionalProperties=$additionalProperties}" + } + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare experiments + */ + @NoAutoDetect + class Scores + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Scores = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Scores]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scores]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scores: Scores) = apply { + additionalProperties = scores.additionalProperties.toMutableMap() + } + + 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 [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InsertExperimentEvent && id == other.id && _isMerge == other._isMerge && _mergePaths == other._mergePaths && _objectDelete == other._objectDelete && _parentId == other._parentId && context == other.context && created == other.created && error == other.error && expected == other.expected && input == other.input && metadata == other.metadata && metrics == other.metrics && origin == other.origin && output == other.output && rootSpanId == other.rootSpanId && scores == other.scores && spanAttributes == other.spanAttributes && spanId == other.spanId && spanParents == other.spanParents && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _isMerge, _mergePaths, _objectDelete, _parentId, context, created, error, expected, input, metadata, metrics, origin, output, rootSpanId, scores, spanAttributes, spanId, spanParents, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InsertExperimentEvent{id=$id, _isMerge=$_isMerge, _mergePaths=$_mergePaths, _objectDelete=$_objectDelete, _parentId=$_parentId, context=$context, created=$created, error=$error, expected=$expected, input=$input, metadata=$metadata, metrics=$metrics, origin=$origin, output=$output, rootSpanId=$rootSpanId, scores=$scores, spanAttributes=$spanAttributes, spanId=$spanId, spanParents=$spanParents, tags=$tags, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventMerge.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventMerge.kt deleted file mode 100755 index bfc1a9ff..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventMerge.kt +++ /dev/null @@ -1,1478 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertExperimentEventMerge.Builder::class) -@NoAutoDetect -class InsertExperimentEventMerge -private constructor( - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanAttributes: JsonField, - private val id: JsonField, - private val datasetRecordId: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _mergePaths: JsonField>>, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical - */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question - */ - fun output(): JsonValue = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate your experiments while - * digging into analyses. However, we may later use these values to re-score outputs or - * fine-tune your models - */ - fun expected(): JsonValue = expected - - /** The error that occurred, if any. */ - fun error(): JsonValue = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(): Optional = - Optional.ofNullable(spanAttributes.getNullable("span_attributes")) - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - fun datasetRecordId(): Optional = - Optional.ofNullable(datasetRecordId.getNullable("dataset_record_id")) - - /** The timestamp the experiment event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not show - * up in subsequent fetches for this experiment - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Boolean = _isMerge.getRequired("_is_merge") - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - fun _mergePaths(): Optional>> = - Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical - */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question - */ - @JsonProperty("output") @ExcludeMissing fun _output() = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate your experiments while - * digging into analyses. However, we may later use these values to re-score outputs or - * fine-tune your models - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - @JsonProperty("context") @ExcludeMissing fun _context() = context - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - @JsonProperty("dataset_record_id") @ExcludeMissing fun _datasetRecordId() = datasetRecordId - - /** The timestamp the experiment event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not show - * up in subsequent fetches for this experiment - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - @JsonProperty("_merge_paths") @ExcludeMissing fun __mergePaths() = _mergePaths - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertExperimentEventMerge = apply { - if (!validated) { - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanAttributes().map { it.validate() } - id() - datasetRecordId() - created() - _objectDelete() - _isMerge() - _mergePaths() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertExperimentEventMerge && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanAttributes == other.spanAttributes && - this.id == other.id && - this.datasetRecordId == other.datasetRecordId && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._mergePaths == other._mergePaths && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanAttributes, - id, - datasetRecordId, - created, - _objectDelete, - _isMerge, - _mergePaths, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertExperimentEventMerge{input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanAttributes=$spanAttributes, id=$id, datasetRecordId=$datasetRecordId, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _mergePaths=$_mergePaths, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanAttributes: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var datasetRecordId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _mergePaths: JsonField>> = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertExperimentEventMerge: InsertExperimentEventMerge) = apply { - this.input = insertExperimentEventMerge.input - this.output = insertExperimentEventMerge.output - this.expected = insertExperimentEventMerge.expected - this.error = insertExperimentEventMerge.error - this.scores = insertExperimentEventMerge.scores - this.metadata = insertExperimentEventMerge.metadata - this.tags = insertExperimentEventMerge.tags - this.metrics = insertExperimentEventMerge.metrics - this.context = insertExperimentEventMerge.context - this.spanAttributes = insertExperimentEventMerge.spanAttributes - this.id = insertExperimentEventMerge.id - this.datasetRecordId = insertExperimentEventMerge.datasetRecordId - this.created = insertExperimentEventMerge.created - this._objectDelete = insertExperimentEventMerge._objectDelete - this._isMerge = insertExperimentEventMerge._isMerge - this._mergePaths = insertExperimentEventMerge._mergePaths - additionalProperties(insertExperimentEventMerge.additionalProperties) - } - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same - * between experiments, so they should not contain experiment-specific state. A simple rule - * of thumb is that if you run the same experiment twice, the `input` should be identical - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question - */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does - * not compare `output` to `expected` for you, since there are so many different ways to do - * that correctly. Instead, these values are just used to help you navigate your experiments - * while digging into analyses. However, we may later use these values to re-score outputs - * or fine-tune your models - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments - */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } - - /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event - */ - fun context(context: Context) = context(JsonField.of(context)) - - /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event - */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes - } - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - fun datasetRecordId(datasetRecordId: String) = - datasetRecordId(JsonField.of(datasetRecordId)) - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - @JsonProperty("dataset_record_id") - @ExcludeMissing - fun datasetRecordId(datasetRecordId: JsonField) = apply { - this.datasetRecordId = datasetRecordId - } - - /** The timestamp the experiment event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the experiment event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not - * show up in subsequent fetches for this experiment - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not - * show up in subsequent fetches for this experiment - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - fun _mergePaths(_mergePaths: List>) = _mergePaths(JsonField.of(_mergePaths)) - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - @JsonProperty("_merge_paths") - @ExcludeMissing - fun _mergePaths(_mergePaths: JsonField>>) = apply { - this._mergePaths = _mergePaths - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertExperimentEventMerge = - InsertExperimentEventMerge( - input, - output, - expected, - error, - scores, - metadata, - tags.map { it.toUnmodifiable() }, - metrics, - context, - spanAttributes, - id, - datasetRecordId, - created, - _objectDelete, - _isMerge, - _mergePaths.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - @JsonDeserialize(builder = Context.Builder::class) - @NoAutoDetect - class Context - private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The function in code which created the experiment event */ - fun callerFunctionname(): Optional = - Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - - /** Name of the file in code where the experiment event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the experiment event was created */ - fun callerLineno(): Optional = - Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - - /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun _callerFunctionname() = callerFunctionname - - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename - - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var callerFunctionname: JsonField = JsonMissing.of() - private var callerFilename: JsonField = JsonMissing.of() - private var callerLineno: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) - } - - /** The function in code which created the experiment event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) - - /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun callerFunctionname(callerFunctionname: JsonField) = apply { - this.callerFunctionname = callerFunctionname - } - - /** Name of the file in code where the experiment event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) - - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } - - /** Line of code where the experiment event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) - - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing - fun callerLineno(callerLineno: JsonField) = apply { - this.callerLineno = callerLineno - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Context = - Context( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonDeserialize(builder = Metrics.Builder::class) - @NoAutoDetect - class Metrics - private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * started - */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * finished - */ - fun end(): Optional = Optional.ofNullable(end.getNullable("end")) - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - fun promptTokens(): Optional = - Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) - - /** The total number of tokens in the input and output of the experiment event. */ - fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * started - */ - @JsonProperty("start") @ExcludeMissing fun _start() = start - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * finished - */ - @JsonProperty("end") @ExcludeMissing fun _end() = end - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens - - /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var start: JsonField = JsonMissing.of() - private var end: JsonField = JsonMissing.of() - private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() - private var tokens: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) - } - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event started - */ - fun start(start: Double) = start(JsonField.of(start)) - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event started - */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event finished - */ - fun end(end: Double) = end(JsonField.of(end)) - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event finished - */ - @JsonProperty("end") - @ExcludeMissing - fun end(end: JsonField) = apply { this.end = end } - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") - @ExcludeMissing - fun promptTokens(promptTokens: JsonField) = apply { - this.promptTokens = promptTokens - } - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } - - /** The total number of tokens in the input and output of the experiment event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) - - /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") - @ExcludeMissing - fun tokens(tokens: JsonField) = apply { this.tokens = tokens } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metrics = - Metrics( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - @JsonDeserialize(builder = Scores.Builder::class) - @NoAutoDetect - class Scores - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Scores{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplace.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplace.kt deleted file mode 100755 index 41a1ffb7..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplace.kt +++ /dev/null @@ -1,1471 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertExperimentEventReplace.Builder::class) -@NoAutoDetect -class InsertExperimentEventReplace -private constructor( - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanAttributes: JsonField, - private val id: JsonField, - private val datasetRecordId: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _parentId: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical - */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question - */ - fun output(): JsonValue = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate your experiments while - * digging into analyses. However, we may later use these values to re-score outputs or - * fine-tune your models - */ - fun expected(): JsonValue = expected - - /** The error that occurred, if any. */ - fun error(): JsonValue = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(): Optional = - Optional.ofNullable(spanAttributes.getNullable("span_attributes")) - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - fun datasetRecordId(): Optional = - Optional.ofNullable(datasetRecordId.getNullable("dataset_record_id")) - - /** The timestamp the experiment event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not show - * up in subsequent fetches for this experiment - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same between - * experiments, so they should not contain experiment-specific state. A simple rule of thumb is - * that if you run the same experiment twice, the `input` should be identical - */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question - */ - @JsonProperty("output") @ExcludeMissing fun _output() = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate your experiments while - * digging into analyses. However, we may later use these values to re-score outputs or - * fine-tune your models - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - @JsonProperty("context") @ExcludeMissing fun _context() = context - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - @JsonProperty("dataset_record_id") @ExcludeMissing fun _datasetRecordId() = datasetRecordId - - /** The timestamp the experiment event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not show - * up in subsequent fetches for this experiment - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") @ExcludeMissing fun __parentId() = _parentId - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertExperimentEventReplace = apply { - if (!validated) { - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanAttributes().map { it.validate() } - id() - datasetRecordId() - created() - _objectDelete() - _isMerge() - _parentId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertExperimentEventReplace && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanAttributes == other.spanAttributes && - this.id == other.id && - this.datasetRecordId == other.datasetRecordId && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._parentId == other._parentId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanAttributes, - id, - datasetRecordId, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertExperimentEventReplace{input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanAttributes=$spanAttributes, id=$id, datasetRecordId=$datasetRecordId, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _parentId=$_parentId, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanAttributes: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var datasetRecordId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _parentId: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertExperimentEventReplace: InsertExperimentEventReplace) = apply { - this.input = insertExperimentEventReplace.input - this.output = insertExperimentEventReplace.output - this.expected = insertExperimentEventReplace.expected - this.error = insertExperimentEventReplace.error - this.scores = insertExperimentEventReplace.scores - this.metadata = insertExperimentEventReplace.metadata - this.tags = insertExperimentEventReplace.tags - this.metrics = insertExperimentEventReplace.metrics - this.context = insertExperimentEventReplace.context - this.spanAttributes = insertExperimentEventReplace.spanAttributes - this.id = insertExperimentEventReplace.id - this.datasetRecordId = insertExperimentEventReplace.datasetRecordId - this.created = insertExperimentEventReplace.created - this._objectDelete = insertExperimentEventReplace._objectDelete - this._isMerge = insertExperimentEventReplace._isMerge - this._parentId = insertExperimentEventReplace._parentId - additionalProperties(insertExperimentEventReplace.additionalProperties) - } - - /** - * The arguments that uniquely define a test case (an arbitrary, JSON serializable object). - * Later on, Braintrust will use the `input` to know whether two test cases are the same - * between experiments, so they should not contain experiment-specific state. A simple rule - * of thumb is that if you run the same experiment twice, the `input` should be identical - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question - */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does - * not compare `output` to `expected` for you, since there are so many different ways to do - * that correctly. Instead, these values are just used to help you navigate your experiments - * while digging into analyses. However, we may later use these values to re-score outputs - * or fine-tune your models - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare experiments - */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } - - /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event - */ - fun context(context: Context) = context(JsonField.of(context)) - - /** - * Context is additional information about the code that produced the experiment event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the experiment event - */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes - } - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the experiment event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - fun datasetRecordId(datasetRecordId: String) = - datasetRecordId(JsonField.of(datasetRecordId)) - - /** - * If the experiment is associated to a dataset, this is the event-level dataset id this - * experiment event is tied to - */ - @JsonProperty("dataset_record_id") - @ExcludeMissing - fun datasetRecordId(datasetRecordId: JsonField) = apply { - this.datasetRecordId = datasetRecordId - } - - /** The timestamp the experiment event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the experiment event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not - * show up in subsequent fetches for this experiment - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the experiment event deleted. Deleted events will not - * show up in subsequent fetches for this experiment - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(_parentId: String) = _parentId(JsonField.of(_parentId)) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") - @ExcludeMissing - fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertExperimentEventReplace = - InsertExperimentEventReplace( - input, - output, - expected, - error, - scores, - metadata, - tags.map { it.toUnmodifiable() }, - metrics, - context, - spanAttributes, - id, - datasetRecordId, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * Context is additional information about the code that produced the experiment event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the experiment event - */ - @JsonDeserialize(builder = Context.Builder::class) - @NoAutoDetect - class Context - private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The function in code which created the experiment event */ - fun callerFunctionname(): Optional = - Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - - /** Name of the file in code where the experiment event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the experiment event was created */ - fun callerLineno(): Optional = - Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - - /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun _callerFunctionname() = callerFunctionname - - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename - - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var callerFunctionname: JsonField = JsonMissing.of() - private var callerFilename: JsonField = JsonMissing.of() - private var callerLineno: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) - } - - /** The function in code which created the experiment event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) - - /** The function in code which created the experiment event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun callerFunctionname(callerFunctionname: JsonField) = apply { - this.callerFunctionname = callerFunctionname - } - - /** Name of the file in code where the experiment event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) - - /** Name of the file in code where the experiment event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } - - /** Line of code where the experiment event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) - - /** Line of code where the experiment event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing - fun callerLineno(callerLineno: JsonField) = apply { - this.callerLineno = callerLineno - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Context = - Context( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * experiment event. Use "start" and "end" to track the time span over which the experiment - * event was produced - */ - @JsonDeserialize(builder = Metrics.Builder::class) - @NoAutoDetect - class Metrics - private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * started - */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * finished - */ - fun end(): Optional = Optional.ofNullable(end.getNullable("end")) - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - fun promptTokens(): Optional = - Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) - - /** The total number of tokens in the input and output of the experiment event. */ - fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * started - */ - @JsonProperty("start") @ExcludeMissing fun _start() = start - - /** - * A unix timestamp recording when the section of code which produced the experiment event - * finished - */ - @JsonProperty("end") @ExcludeMissing fun _end() = end - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens - - /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var start: JsonField = JsonMissing.of() - private var end: JsonField = JsonMissing.of() - private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() - private var tokens: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) - } - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event started - */ - fun start(start: Double) = start(JsonField.of(start)) - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event started - */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event finished - */ - fun end(end: Double) = end(JsonField.of(end)) - - /** - * A unix timestamp recording when the section of code which produced the experiment - * event finished - */ - @JsonProperty("end") - @ExcludeMissing - fun end(end: JsonField) = apply { this.end = end } - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) - - /** - * The number of tokens in the prompt used to generate the experiment event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") - @ExcludeMissing - fun promptTokens(promptTokens: JsonField) = apply { - this.promptTokens = promptTokens - } - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } - - /** The total number of tokens in the input and output of the experiment event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) - - /** The total number of tokens in the input and output of the experiment event. */ - @JsonProperty("tokens") - @ExcludeMissing - fun tokens(tokens: JsonField) = apply { this.tokens = tokens } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metrics = - Metrics( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare experiments - */ - @JsonDeserialize(builder = Scores.Builder::class) - @NoAutoDetect - class Scores - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Scores{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEvent.kt new file mode 100644 index 00000000..af3e8ffb --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEvent.kt @@ -0,0 +1,1887 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.time.OffsetDateTime +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A project logs event */ +@NoAutoDetect +class InsertProjectLogsEvent +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_is_merge") + @ExcludeMissing + private val _isMerge: JsonField = JsonMissing.of(), + @JsonProperty("_merge_paths") + @ExcludeMissing + private val _mergePaths: JsonField>> = JsonMissing.of(), + @JsonProperty("_object_delete") + @ExcludeMissing + private val _objectDelete: JsonField = JsonMissing.of(), + @JsonProperty("_parent_id") + @ExcludeMissing + private val _parentId: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + private val context: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing private val error: JsonValue = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("metrics") + @ExcludeMissing + private val metrics: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("output") @ExcludeMissing private val output: JsonValue = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("span_attributes") + @ExcludeMissing + private val spanAttributes: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("span_parents") + @ExcludeMissing + private val spanParents: JsonField> = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * A unique identifier for the project logs event. If you don't provide one, BrainTrust will + * generate one for you + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = Optional.ofNullable(id.getNullable("id")) + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same id + * in the DB. By default (or when set to `false`), the existing row is completely replaced by + * the new row. When set to `true`, the new row is deep-merged into the existing row, if one is + * found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when `_is_merge=true`. + * `_merge_paths` is a list of paths, where each path is a list of field names. The deep merge + * will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, + * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, + * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, + * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": + * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the + * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and + * `input.c`. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _mergePaths(): Optional>> = + Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) + + /** + * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will not + * show up in subsequent fetches for this project logs + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _objectDelete(): Optional = + Optional.ofNullable(_objectDelete.getNullable("_object_delete")) + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent + * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after + * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row + * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this + * case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) + + /** + * Context is additional information about the code that produced the project logs event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + + /** + * The timestamp the project logs event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** The error that occurred, if any. */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonValue = error + + /** + * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to + * `output` to determine if your `output` value is correct or not. Braintrust currently does not + * compare `output` to `expected` for you, since there are so many different ways to do that + * correctly. Instead, these values are just used to help you navigate while digging into + * analyses. However, we may later use these values to re-score outputs or fine-tune your + * models. + */ + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected + + /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * project logs event. Use "start" and "end" to track the time span over which the project logs + * event was produced + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) + + /** + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) + + /** + * The output of your application, including post-processing (an arbitrary, JSON serializable + * object), that allows you to determine whether the result is correct or not. For example, in + * an app that generates SQL queries, the `output` should be the _result_ of the SQL query + * generated by the model, not the query itself, because there may be multiple valid queries + * that answer a single question. + */ + @JsonProperty("output") @ExcludeMissing fun _output(): JsonValue = output + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rootSpanId(): Optional = Optional.ofNullable(rootSpanId.getNullable("root_span_id")) + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare logs. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + + /** + * Human-identifying attributes of the span, such as name, type, etc. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanAttributes(): Optional = + Optional.ofNullable(spanAttributes.getNullable("span_attributes")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanId(): Optional = Optional.ofNullable(spanId.getNullable("span_id")) + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, and + * the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": {"correctness": + * 0.33}}`. We can create a sub-span of the parent row by logging `{"id": "llm_call", "span_id": + * "span1", "root_span_id": "root_span0", "span_parents": ["span0"], "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root + * span row `"abc"` will show up in the summary view. You can view the full trace hierarchy (in + * this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanParents(): Optional> = + Optional.ofNullable(spanParents.getNullable("span_parents")) + + /** + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + + /** + * 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 [_isMerge]. + * + * Unlike [_isMerge], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge(): JsonField = _isMerge + + /** + * Returns the raw JSON value of [_mergePaths]. + * + * Unlike [_mergePaths], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_merge_paths") + @ExcludeMissing + fun __mergePaths(): JsonField>> = _mergePaths + + /** + * Returns the raw JSON value of [_objectDelete]. + * + * Unlike [_objectDelete], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_object_delete") + @ExcludeMissing + fun __objectDelete(): JsonField = _objectDelete + + /** + * Returns the raw JSON value of [_parentId]. + * + * Unlike [_parentId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_parent_id") @ExcludeMissing fun __parentId(): JsonField = _parentId + + /** + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + + /** + * Returns the raw JSON value of [metrics]. + * + * Unlike [metrics], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metrics") @ExcludeMissing fun _metrics(): JsonField = metrics + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId + + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores + + /** + * Returns the raw JSON value of [spanAttributes]. + * + * Unlike [spanAttributes], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_attributes") + @ExcludeMissing + fun _spanAttributes(): JsonField = spanAttributes + + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId + + /** + * Returns the raw JSON value of [spanParents]. + * + * Unlike [spanParents], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_parents") + @ExcludeMissing + fun _spanParents(): JsonField> = spanParents + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InsertProjectLogsEvent = apply { + if (validated) { + return@apply + } + + id() + _isMerge() + _mergePaths() + _objectDelete() + _parentId() + context().ifPresent { it.validate() } + created() + metadata().ifPresent { it.validate() } + metrics().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + rootSpanId() + scores().ifPresent { it.validate() } + spanAttributes().ifPresent { it.validate() } + spanId() + spanParents() + tags() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [InsertProjectLogsEvent]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InsertProjectLogsEvent]. */ + class Builder internal constructor() { + + private var id: JsonField = JsonMissing.of() + private var _isMerge: JsonField = JsonMissing.of() + private var _mergePaths: JsonField>>? = null + private var _objectDelete: JsonField = JsonMissing.of() + private var _parentId: JsonField = JsonMissing.of() + private var context: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() + private var error: JsonValue = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var metrics: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var output: JsonValue = JsonMissing.of() + private var rootSpanId: JsonField = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() + private var spanAttributes: JsonField = JsonMissing.of() + private var spanId: JsonField = JsonMissing.of() + private var spanParents: JsonField>? = null + private var tags: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(insertProjectLogsEvent: InsertProjectLogsEvent) = apply { + id = insertProjectLogsEvent.id + _isMerge = insertProjectLogsEvent._isMerge + _mergePaths = insertProjectLogsEvent._mergePaths.map { it.toMutableList() } + _objectDelete = insertProjectLogsEvent._objectDelete + _parentId = insertProjectLogsEvent._parentId + context = insertProjectLogsEvent.context + created = insertProjectLogsEvent.created + error = insertProjectLogsEvent.error + expected = insertProjectLogsEvent.expected + input = insertProjectLogsEvent.input + metadata = insertProjectLogsEvent.metadata + metrics = insertProjectLogsEvent.metrics + origin = insertProjectLogsEvent.origin + output = insertProjectLogsEvent.output + rootSpanId = insertProjectLogsEvent.rootSpanId + scores = insertProjectLogsEvent.scores + spanAttributes = insertProjectLogsEvent.spanAttributes + spanId = insertProjectLogsEvent.spanId + spanParents = insertProjectLogsEvent.spanParents.map { it.toMutableList() } + tags = insertProjectLogsEvent.tags.map { it.toMutableList() } + additionalProperties = insertProjectLogsEvent.additionalProperties.toMutableMap() + } + + /** + * A unique identifier for the project logs event. If you don't provide one, BrainTrust will + * generate one for you + */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * 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 } + + /** + * The `_is_merge` field controls how the row is merged with any existing row with the same + * id in the DB. By default (or when set to `false`), the existing row is completely + * replaced by the new row. When set to `true`, the new row is deep-merged into the existing + * row, if one is found. If no existing row is found, the new row is inserted as is. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": + * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": + * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we + * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be + * `{"id": "foo", "input": {"b": 11, "c": 20}}` + */ + fun _isMerge(_isMerge: Boolean?) = _isMerge(JsonField.ofNullable(_isMerge)) + + /** + * Alias for [Builder._isMerge]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _isMerge(_isMerge: Boolean) = _isMerge(_isMerge as Boolean?) + + /** Alias for calling [Builder._isMerge] with `_isMerge.orElse(null)`. */ + fun _isMerge(_isMerge: Optional) = _isMerge(_isMerge.getOrNull()) + + /** + * Sets [Builder._isMerge] to an arbitrary JSON value. + * + * You should usually call [Builder._isMerge] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } + + /** + * The `_merge_paths` field allows controlling the depth of the merge, when + * `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of field + * names. The deep merge will not descend below any of the specified merge paths. + * + * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": + * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": + * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": + * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": + * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this + * case, due to the merge paths, we have replaced `input.a` and `output`, but have still + * deep-merged `input` and `input.c`. + */ + fun _mergePaths(_mergePaths: List>?) = + _mergePaths(JsonField.ofNullable(_mergePaths)) + + /** Alias for calling [Builder._mergePaths] with `_mergePaths.orElse(null)`. */ + fun _mergePaths(_mergePaths: Optional>>) = + _mergePaths(_mergePaths.getOrNull()) + + /** + * Sets [Builder._mergePaths] to an arbitrary JSON value. + * + * You should usually call [Builder._mergePaths] with a well-typed `List>` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun _mergePaths(_mergePaths: JsonField>>) = apply { + this._mergePaths = _mergePaths.map { it.toMutableList() } + } + + /** + * Adds a single [List] to [_mergePaths]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMergePath(mergePath: List) = apply { + _mergePaths = + (_mergePaths ?: JsonField.of(mutableListOf())).also { + checkKnown("_mergePaths", it).add(mergePath) + } + } + + /** + * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will + * not show up in subsequent fetches for this project logs + */ + fun _objectDelete(_objectDelete: Boolean?) = + _objectDelete(JsonField.ofNullable(_objectDelete)) + + /** + * Alias for [Builder._objectDelete]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun _objectDelete(_objectDelete: Boolean) = _objectDelete(_objectDelete as Boolean?) + + /** Alias for calling [Builder._objectDelete] with `_objectDelete.orElse(null)`. */ + fun _objectDelete(_objectDelete: Optional) = + _objectDelete(_objectDelete.getOrNull()) + + /** + * Sets [Builder._objectDelete] to an arbitrary JSON value. + * + * You should usually call [Builder._objectDelete] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun _objectDelete(_objectDelete: JsonField) = apply { + this._objectDelete = _objectDelete + } + + /** + * DEPRECATED: The `_parent_id` field is deprecated and should not be used. Support for + * `_parent_id` will be dropped in a future version of Braintrust. Log `span_id`, + * `root_span_id`, and `span_parents` explicitly instead. + * + * Use the `_parent_id` field to create this row as a subspan of an existing row. Tracking + * hierarchical relationships are important for tracing (see the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). + * + * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", + * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the + * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What + * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the + * root span row `"abc"` will show up in the summary view. You can view the full trace + * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun _parentId(_parentId: String?) = _parentId(JsonField.ofNullable(_parentId)) + + /** Alias for calling [Builder._parentId] with `_parentId.orElse(null)`. */ + fun _parentId(_parentId: Optional) = _parentId(_parentId.getOrNull()) + + /** + * Sets [Builder._parentId] to an arbitrary JSON value. + * + * You should usually call [Builder._parentId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } + + /** + * Context is additional information about the code that produced the project logs event. It + * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to + * track the location in code which produced the project logs event + */ + fun context(context: Context?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [Context] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + /** The timestamp the project logs event was created */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** The error that occurred, if any. */ + fun error(error: JsonValue) = apply { this.error = error } + + /** + * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to + * `output` to determine if your `output` value is correct or not. Braintrust currently does + * not compare `output` to `expected` for you, since there are so many different ways to do + * that correctly. Instead, these values are just used to help you navigate while digging + * into analyses. However, we may later use these values to re-score outputs or fine-tune + * your models. + */ + fun expected(expected: JsonValue) = apply { this.expected = expected } + + /** + * The arguments that uniquely define a user input (an arbitrary, JSON serializable object). + */ + fun input(input: JsonValue) = apply { this.input = input } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. + * For example, you could log the `prompt`, example's `id`, or anything else that would be + * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, + * but its keys must be strings + */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * project logs event. Use "start" and "end" to track the time span over which the project + * logs event was produced + */ + fun metrics(metrics: Metrics?) = metrics(JsonField.ofNullable(metrics)) + + /** Alias for calling [Builder.metrics] with `metrics.orElse(null)`. */ + fun metrics(metrics: Optional) = metrics(metrics.getOrNull()) + + /** + * Sets [Builder.metrics] to an arbitrary JSON value. + * + * You should usually call [Builder.metrics] with a well-typed [Metrics] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) + + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } + + /** + * The output of your application, including post-processing (an arbitrary, JSON + * serializable object), that allows you to determine whether the result is correct or not. + * For example, in an app that generates SQL queries, the `output` should be the _result_ of + * the SQL query generated by the model, not the query itself, because there may be multiple + * valid queries that answer a single question. + */ + fun output(output: JsonValue) = apply { this.output = output } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun rootSpanId(rootSpanId: String?) = rootSpanId(JsonField.ofNullable(rootSpanId)) + + /** Alias for calling [Builder.rootSpanId] with `rootSpanId.orElse(null)`. */ + fun rootSpanId(rootSpanId: Optional) = rootSpanId(rootSpanId.getOrNull()) + + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a + * variety of signals that help you determine how accurate the outputs are compared to what + * you expect and diagnose failures. For example, a summarization app might have one score + * that tells you how accurate the summary is, and another that measures the word similarity + * between the generated and grouth truth summary. The word similarity score could help you + * determine whether the summarization was covering similar concepts or not. You can use + * these scores to help you sort, filter, and compare logs. + */ + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) + + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } + + /** Human-identifying attributes of the span, such as name, type, etc. */ + fun spanAttributes(spanAttributes: SpanAttributes?) = + spanAttributes(JsonField.ofNullable(spanAttributes)) + + /** Alias for calling [Builder.spanAttributes] with `spanAttributes.orElse(null)`. */ + fun spanAttributes(spanAttributes: Optional) = + spanAttributes(spanAttributes.getOrNull()) + + /** + * Sets [Builder.spanAttributes] to an arbitrary JSON value. + * + * You should usually call [Builder.spanAttributes] with a well-typed [SpanAttributes] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun spanAttributes(spanAttributes: JsonField) = apply { + this.spanAttributes = spanAttributes + } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanId(spanId: String?) = spanId(JsonField.ofNullable(spanId)) + + /** Alias for calling [Builder.spanId] with `spanId.orElse(null)`. */ + fun spanId(spanId: Optional) = spanId(spanId.getOrNull()) + + /** + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + + /** + * Use `span_id`, `root_span_id`, and `span_parents` instead of `_parent_id`, which is now + * deprecated. The span_id is a unique identifier describing the row's place in the a trace, + * and the root_span_id is a unique identifier for the whole trace. See the + * [guide](https://www.braintrust.dev/docs/guides/tracing) for full details. + * + * For example, say we have logged a row `{"id": "abc", "span_id": "span0", "root_span_id": + * "root_span0", "input": "foo", "output": "bar", "expected": "boo", "scores": + * {"correctness": 0.33}}`. We can create a sub-span of the parent row by logging `{"id": + * "llm_call", "span_id": "span1", "root_span_id": "root_span0", "span_parents": ["span0"], + * "input": {"prompt": "What comes after foo?"}, "output": "bar", "metrics": {"tokens": + * 1}}`. In the webapp, only the root span row `"abc"` will show up in the summary view. You + * can view the full trace hierarchy (in this case, the `"llm_call"` row) by clicking on the + * "abc" row. + * + * If the row is being merged into an existing row, this field will be ignored. + */ + fun spanParents(spanParents: List?) = spanParents(JsonField.ofNullable(spanParents)) + + /** Alias for calling [Builder.spanParents] with `spanParents.orElse(null)`. */ + fun spanParents(spanParents: Optional>) = spanParents(spanParents.getOrNull()) + + /** + * Sets [Builder.spanParents] to an arbitrary JSON value. + * + * You should usually call [Builder.spanParents] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun spanParents(spanParents: JsonField>) = apply { + this.spanParents = spanParents.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [spanParents]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanParent(spanParent: String) = apply { + spanParents = + (spanParents ?: JsonField.of(mutableListOf())).also { + checkKnown("spanParents", it).add(spanParent) + } + } + + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 [InsertProjectLogsEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): InsertProjectLogsEvent = + InsertProjectLogsEvent( + id, + _isMerge, + (_mergePaths ?: JsonMissing.of()).map { it.toImmutable() }, + _objectDelete, + _parentId, + context, + created, + error, + expected, + input, + metadata, + metrics, + origin, + output, + rootSpanId, + scores, + spanAttributes, + spanId, + (spanParents ?: JsonMissing.of()).map { it.toImmutable() }, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } + + /** + * Context is additional information about the code that produced the project logs event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the project logs event + */ + @NoAutoDetect + class Context + @JsonCreator + private constructor( + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonField = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonField = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * Name of the file in code where the project logs event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFilename(): Optional = + Optional.ofNullable(callerFilename.getNullable("caller_filename")) + + /** + * The function in code which created the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFunctionname(): Optional = + Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) + + /** + * Line of code where the project logs event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerLineno(): Optional = + Optional.ofNullable(callerLineno.getNullable("caller_lineno")) + + /** + * Returns the raw JSON value of [callerFilename]. + * + * Unlike [callerFilename], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonField = callerFilename + + /** + * Returns the raw JSON value of [callerFunctionname]. + * + * Unlike [callerFunctionname], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonField = callerFunctionname + + /** + * Returns the raw JSON value of [callerLineno]. + * + * Unlike [callerLineno], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_lineno") + @ExcludeMissing + fun _callerLineno(): JsonField = callerLineno + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Context = apply { + if (validated) { + return@apply + } + + callerFilename() + callerFunctionname() + callerLineno() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Context]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Context]. */ + class Builder internal constructor() { + + private var callerFilename: JsonField = JsonMissing.of() + private var callerFunctionname: JsonField = JsonMissing.of() + private var callerLineno: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(context: Context) = apply { + callerFilename = context.callerFilename + callerFunctionname = context.callerFunctionname + callerLineno = context.callerLineno + additionalProperties = context.additionalProperties.toMutableMap() + } + + /** Name of the file in code where the project logs event was created */ + fun callerFilename(callerFilename: String?) = + callerFilename(JsonField.ofNullable(callerFilename)) + + /** Alias for calling [Builder.callerFilename] with `callerFilename.orElse(null)`. */ + fun callerFilename(callerFilename: Optional) = + callerFilename(callerFilename.getOrNull()) + + /** + * Sets [Builder.callerFilename] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFilename] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFilename(callerFilename: JsonField) = apply { + this.callerFilename = callerFilename + } + + /** The function in code which created the project logs event */ + fun callerFunctionname(callerFunctionname: String?) = + callerFunctionname(JsonField.ofNullable(callerFunctionname)) + + /** + * Alias for calling [Builder.callerFunctionname] with + * `callerFunctionname.orElse(null)`. + */ + fun callerFunctionname(callerFunctionname: Optional) = + callerFunctionname(callerFunctionname.getOrNull()) + + /** + * Sets [Builder.callerFunctionname] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFunctionname] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFunctionname(callerFunctionname: JsonField) = apply { + this.callerFunctionname = callerFunctionname + } + + /** Line of code where the project logs event was created */ + fun callerLineno(callerLineno: Long?) = callerLineno(JsonField.ofNullable(callerLineno)) + + /** + * Alias for [Builder.callerLineno]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun callerLineno(callerLineno: Long) = callerLineno(callerLineno as Long?) + + /** Alias for calling [Builder.callerLineno] with `callerLineno.orElse(null)`. */ + fun callerLineno(callerLineno: Optional) = callerLineno(callerLineno.getOrNull()) + + /** + * Sets [Builder.callerLineno] to an arbitrary JSON value. + * + * You should usually call [Builder.callerLineno] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerLineno(callerLineno: JsonField) = apply { + this.callerLineno = callerLineno + } + + 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 [Context]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Context = + Context( + callerFilename, + callerFunctionname, + callerLineno, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Context && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Context{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" + } + + /** + * A dictionary with additional data about the test example, model outputs, or just about + * anything else that's relevant, that you can use to help find and analyze examples later. For + * example, you could log the `prompt`, example's `id`, or anything else that would be useful to + * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys + * must be strings + */ + @NoAutoDetect + class Metadata + @JsonCreator + private constructor( + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metadata = apply { + if (validated) { + return@apply + } + + model() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metadata]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() + } + + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + 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 [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" + } + + /** + * Metrics are numerical measurements tracking the execution of the code that produced the + * project logs event. Use "start" and "end" to track the time span over which the project logs + * event was produced + */ + @NoAutoDetect + class Metrics + @JsonCreator + private constructor( + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonValue = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonValue = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonValue = JsonMissing.of(), + @JsonProperty("completion_tokens") + @ExcludeMissing + private val completionTokens: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing private val end: JsonField = JsonMissing.of(), + @JsonProperty("prompt_tokens") + @ExcludeMissing + private val promptTokens: JsonField = JsonMissing.of(), + @JsonProperty("start") + @ExcludeMissing + private val start: JsonField = JsonMissing.of(), + @JsonProperty("tokens") + @ExcludeMissing + private val tokens: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** This metric is deprecated */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonValue = callerFilename + + /** This metric is deprecated */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonValue = callerFunctionname + + /** This metric is deprecated */ + @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno(): JsonValue = callerLineno + + /** + * The number of tokens in the completion generated by the model (only set if this is an LLM + * span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun completionTokens(): Optional = + Optional.ofNullable(completionTokens.getNullable("completion_tokens")) + + /** + * A unix timestamp recording when the section of code which produced the project logs event + * finished + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun end(): Optional = Optional.ofNullable(end.getNullable("end")) + + /** + * The number of tokens in the prompt used to generate the project logs event (only set if + * this is an LLM span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptTokens(): Optional = + Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) + + /** + * A unix timestamp recording when the section of code which produced the project logs event + * started + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun start(): Optional = Optional.ofNullable(start.getNullable("start")) + + /** + * The total number of tokens in the input and output of the project logs event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) + + /** + * Returns the raw JSON value of [completionTokens]. + * + * Unlike [completionTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("completion_tokens") + @ExcludeMissing + fun _completionTokens(): JsonField = completionTokens + + /** + * Returns the raw JSON value of [end]. + * + * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end + + /** + * Returns the raw JSON value of [promptTokens]. + * + * Unlike [promptTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("prompt_tokens") + @ExcludeMissing + fun _promptTokens(): JsonField = promptTokens + + /** + * Returns the raw JSON value of [start]. + * + * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start + + /** + * Returns the raw JSON value of [tokens]. + * + * Unlike [tokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tokens") @ExcludeMissing fun _tokens(): JsonField = tokens + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Metrics = apply { + if (validated) { + return@apply + } + + completionTokens() + end() + promptTokens() + start() + tokens() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Metrics]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Metrics]. */ + class Builder internal constructor() { + + private var callerFilename: JsonValue = JsonMissing.of() + private var callerFunctionname: JsonValue = JsonMissing.of() + private var callerLineno: JsonValue = JsonMissing.of() + private var completionTokens: JsonField = JsonMissing.of() + private var end: JsonField = JsonMissing.of() + private var promptTokens: JsonField = JsonMissing.of() + private var start: JsonField = JsonMissing.of() + private var tokens: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(metrics: Metrics) = apply { + callerFilename = metrics.callerFilename + callerFunctionname = metrics.callerFunctionname + callerLineno = metrics.callerLineno + completionTokens = metrics.completionTokens + end = metrics.end + promptTokens = metrics.promptTokens + start = metrics.start + tokens = metrics.tokens + additionalProperties = metrics.additionalProperties.toMutableMap() + } + + /** This metric is deprecated */ + fun callerFilename(callerFilename: JsonValue) = apply { + this.callerFilename = callerFilename + } + + /** This metric is deprecated */ + fun callerFunctionname(callerFunctionname: JsonValue) = apply { + this.callerFunctionname = callerFunctionname + } + + /** This metric is deprecated */ + fun callerLineno(callerLineno: JsonValue) = apply { this.callerLineno = callerLineno } + + /** + * The number of tokens in the completion generated by the model (only set if this is an + * LLM span) + */ + fun completionTokens(completionTokens: Long?) = + completionTokens(JsonField.ofNullable(completionTokens)) + + /** + * Alias for [Builder.completionTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun completionTokens(completionTokens: Long) = + completionTokens(completionTokens as Long?) + + /** + * Alias for calling [Builder.completionTokens] with `completionTokens.orElse(null)`. + */ + fun completionTokens(completionTokens: Optional) = + completionTokens(completionTokens.getOrNull()) + + /** + * Sets [Builder.completionTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.completionTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun completionTokens(completionTokens: JsonField) = apply { + this.completionTokens = completionTokens + } + + /** + * A unix timestamp recording when the section of code which produced the project logs + * event finished + */ + fun end(end: Double?) = end(JsonField.ofNullable(end)) + + /** + * Alias for [Builder.end]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun end(end: Double) = end(end as Double?) + + /** Alias for calling [Builder.end] with `end.orElse(null)`. */ + fun end(end: Optional) = end(end.getOrNull()) + + /** + * Sets [Builder.end] to an arbitrary JSON value. + * + * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun end(end: JsonField) = apply { this.end = end } + + /** + * The number of tokens in the prompt used to generate the project logs event (only set + * if this is an LLM span) + */ + fun promptTokens(promptTokens: Long?) = promptTokens(JsonField.ofNullable(promptTokens)) + + /** + * Alias for [Builder.promptTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun promptTokens(promptTokens: Long) = promptTokens(promptTokens as Long?) + + /** Alias for calling [Builder.promptTokens] with `promptTokens.orElse(null)`. */ + fun promptTokens(promptTokens: Optional) = promptTokens(promptTokens.getOrNull()) + + /** + * Sets [Builder.promptTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.promptTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptTokens(promptTokens: JsonField) = apply { + this.promptTokens = promptTokens + } + + /** + * A unix timestamp recording when the section of code which produced the project logs + * event started + */ + fun start(start: Double?) = start(JsonField.ofNullable(start)) + + /** + * Alias for [Builder.start]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun start(start: Double) = start(start as Double?) + + /** Alias for calling [Builder.start] with `start.orElse(null)`. */ + fun start(start: Optional) = start(start.getOrNull()) + + /** + * Sets [Builder.start] to an arbitrary JSON value. + * + * You should usually call [Builder.start] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun start(start: JsonField) = apply { this.start = start } + + /** The total number of tokens in the input and output of the project logs event. */ + fun tokens(tokens: Long?) = tokens(JsonField.ofNullable(tokens)) + + /** + * Alias for [Builder.tokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun tokens(tokens: Long) = tokens(tokens as Long?) + + /** Alias for calling [Builder.tokens] with `tokens.orElse(null)`. */ + fun tokens(tokens: Optional) = tokens(tokens.getOrNull()) + + /** + * Sets [Builder.tokens] to an arbitrary JSON value. + * + * You should usually call [Builder.tokens] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tokens(tokens: JsonField) = apply { this.tokens = tokens } + + 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 [Metrics]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metrics = + Metrics( + callerFilename, + callerFunctionname, + callerLineno, + completionTokens, + end, + promptTokens, + start, + tokens, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metrics && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && completionTokens == other.completionTokens && end == other.end && promptTokens == other.promptTokens && start == other.start && tokens == other.tokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, completionTokens, end, promptTokens, start, tokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metrics{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, completionTokens=$completionTokens, end=$end, promptTokens=$promptTokens, start=$start, tokens=$tokens, additionalProperties=$additionalProperties}" + } + + /** + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare logs. + */ + @NoAutoDetect + class Scores + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Scores = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Scores]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Scores]. */ + class Builder internal constructor() { + + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(scores: Scores) = apply { + additionalProperties = scores.additionalProperties.toMutableMap() + } + + 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 [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InsertProjectLogsEvent && id == other.id && _isMerge == other._isMerge && _mergePaths == other._mergePaths && _objectDelete == other._objectDelete && _parentId == other._parentId && context == other.context && created == other.created && error == other.error && expected == other.expected && input == other.input && metadata == other.metadata && metrics == other.metrics && origin == other.origin && output == other.output && rootSpanId == other.rootSpanId && scores == other.scores && spanAttributes == other.spanAttributes && spanId == other.spanId && spanParents == other.spanParents && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _isMerge, _mergePaths, _objectDelete, _parentId, context, created, error, expected, input, metadata, metrics, origin, output, rootSpanId, scores, spanAttributes, spanId, spanParents, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InsertProjectLogsEvent{id=$id, _isMerge=$_isMerge, _mergePaths=$_mergePaths, _objectDelete=$_objectDelete, _parentId=$_parentId, context=$context, created=$created, error=$error, expected=$expected, input=$input, metadata=$metadata, metrics=$metrics, origin=$origin, output=$output, rootSpanId=$rootSpanId, scores=$scores, spanAttributes=$spanAttributes, spanId=$spanId, spanParents=$spanParents, tags=$tags, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMerge.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMerge.kt deleted file mode 100755 index ed3b51be..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMerge.kt +++ /dev/null @@ -1,1428 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertProjectLogsEventMerge.Builder::class) -@NoAutoDetect -class InsertProjectLogsEventMerge -private constructor( - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanAttributes: JsonField, - private val id: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _mergePaths: JsonField>>, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. - */ - fun output(): JsonValue = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate while digging into - * analyses. However, we may later use these values to re-score outputs or fine-tune your - * models. - */ - fun expected(): JsonValue = expected - - /** The error that occurred, if any. */ - fun error(): JsonValue = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(): Optional = - Optional.ofNullable(spanAttributes.getNullable("span_attributes")) - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** The timestamp the project logs event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will not - * show up in subsequent fetches for this project logs - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Boolean = _isMerge.getRequired("_is_merge") - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - fun _mergePaths(): Optional>> = - Optional.ofNullable(_mergePaths.getNullable("_merge_paths")) - - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. - */ - @JsonProperty("output") @ExcludeMissing fun _output() = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate while digging into - * analyses. However, we may later use these values to re-score outputs or fine-tune your - * models. - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - @JsonProperty("context") @ExcludeMissing fun _context() = context - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The timestamp the project logs event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will not - * show up in subsequent fetches for this project logs - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be specified - * alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path is a list of - * field names. The deep merge will not descend below any of the specified merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": 10}, - * "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": true, - * "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": 30}, - * "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": {"a": {"q": - * 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this case, due to the - * merge paths, we have replaced `input.a` and `output`, but have still deep-merged `input` and - * `input.c`. - */ - @JsonProperty("_merge_paths") @ExcludeMissing fun __mergePaths() = _mergePaths - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertProjectLogsEventMerge = apply { - if (!validated) { - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanAttributes().map { it.validate() } - id() - created() - _objectDelete() - _isMerge() - _mergePaths() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertProjectLogsEventMerge && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanAttributes == other.spanAttributes && - this.id == other.id && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._mergePaths == other._mergePaths && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanAttributes, - id, - created, - _objectDelete, - _isMerge, - _mergePaths, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertProjectLogsEventMerge{input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanAttributes=$spanAttributes, id=$id, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _mergePaths=$_mergePaths, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanAttributes: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _mergePaths: JsonField>> = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertProjectLogsEventMerge: InsertProjectLogsEventMerge) = apply { - this.input = insertProjectLogsEventMerge.input - this.output = insertProjectLogsEventMerge.output - this.expected = insertProjectLogsEventMerge.expected - this.error = insertProjectLogsEventMerge.error - this.scores = insertProjectLogsEventMerge.scores - this.metadata = insertProjectLogsEventMerge.metadata - this.tags = insertProjectLogsEventMerge.tags - this.metrics = insertProjectLogsEventMerge.metrics - this.context = insertProjectLogsEventMerge.context - this.spanAttributes = insertProjectLogsEventMerge.spanAttributes - this.id = insertProjectLogsEventMerge.id - this.created = insertProjectLogsEventMerge.created - this._objectDelete = insertProjectLogsEventMerge._objectDelete - this._isMerge = insertProjectLogsEventMerge._isMerge - this._mergePaths = insertProjectLogsEventMerge._mergePaths - additionalProperties(insertProjectLogsEventMerge.additionalProperties) - } - - /** - * The arguments that uniquely define a user input (an arbitrary, JSON serializable object). - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question. - */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does - * not compare `output` to `expected` for you, since there are so many different ways to do - * that correctly. Instead, these values are just used to help you navigate while digging - * into analyses. However, we may later use these values to re-score outputs or fine-tune - * your models. - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. - */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project - * logs event was produced - */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project - * logs event was produced - */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } - - /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event - */ - fun context(context: Context) = context(JsonField.of(context)) - - /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event - */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes - } - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** The timestamp the project logs event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the project logs event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will - * not show up in subsequent fetches for this project logs - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will - * not show up in subsequent fetches for this project logs - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - fun _mergePaths(_mergePaths: List>) = _mergePaths(JsonField.of(_mergePaths)) - - /** - * The `_merge_paths` field allows controlling the depth of the merge. It can only be - * specified alongside `_is_merge=true`. `_merge_paths` is a list of paths, where each path - * is a list of field names. The deep merge will not descend below any of the specified - * merge paths. - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": {"b": - * 10}, "c": {"d": 20}}, "output": {"a": 20}}`. If we merge a new row as `{"_is_merge": - * true, "_merge_paths": [["input", "a"], ["output"]], "input": {"a": {"q": 30}, "c": {"e": - * 30}, "bar": "baz"}, "output": {"d": 40}}`, the new row will be `{"id": "foo": "input": - * {"a": {"q": 30}, "c": {"d": 20, "e": 30}, "bar": "baz"}, "output": {"d": 40}}`. In this - * case, due to the merge paths, we have replaced `input.a` and `output`, but have still - * deep-merged `input` and `input.c`. - */ - @JsonProperty("_merge_paths") - @ExcludeMissing - fun _mergePaths(_mergePaths: JsonField>>) = apply { - this._mergePaths = _mergePaths - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertProjectLogsEventMerge = - InsertProjectLogsEventMerge( - input, - output, - expected, - error, - scores, - metadata, - tags.map { it.toUnmodifiable() }, - metrics, - context, - spanAttributes, - id, - created, - _objectDelete, - _isMerge, - _mergePaths.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - @JsonDeserialize(builder = Context.Builder::class) - @NoAutoDetect - class Context - private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The function in code which created the project logs event */ - fun callerFunctionname(): Optional = - Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - - /** Name of the file in code where the project logs event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the project logs event was created */ - fun callerLineno(): Optional = - Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - - /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun _callerFunctionname() = callerFunctionname - - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename - - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var callerFunctionname: JsonField = JsonMissing.of() - private var callerFilename: JsonField = JsonMissing.of() - private var callerLineno: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) - } - - /** The function in code which created the project logs event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) - - /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun callerFunctionname(callerFunctionname: JsonField) = apply { - this.callerFunctionname = callerFunctionname - } - - /** Name of the file in code where the project logs event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) - - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } - - /** Line of code where the project logs event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) - - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing - fun callerLineno(callerLineno: JsonField) = apply { - this.callerLineno = callerLineno - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Context = - Context( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - @JsonDeserialize(builder = Metrics.Builder::class) - @NoAutoDetect - class Metrics - private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * started - */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * finished - */ - fun end(): Optional = Optional.ofNullable(end.getNullable("end")) - - /** - * The number of tokens in the prompt used to generate the project logs event (only set if - * this is an LLM span) - */ - fun promptTokens(): Optional = - Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) - - /** The total number of tokens in the input and output of the project logs event. */ - fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * started - */ - @JsonProperty("start") @ExcludeMissing fun _start() = start - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * finished - */ - @JsonProperty("end") @ExcludeMissing fun _end() = end - - /** - * The number of tokens in the prompt used to generate the project logs event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens - - /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var start: JsonField = JsonMissing.of() - private var end: JsonField = JsonMissing.of() - private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() - private var tokens: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) - } - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event started - */ - fun start(start: Double) = start(JsonField.of(start)) - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event started - */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event finished - */ - fun end(end: Double) = end(JsonField.of(end)) - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event finished - */ - @JsonProperty("end") - @ExcludeMissing - fun end(end: JsonField) = apply { this.end = end } - - /** - * The number of tokens in the prompt used to generate the project logs event (only set - * if this is an LLM span) - */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) - - /** - * The number of tokens in the prompt used to generate the project logs event (only set - * if this is an LLM span) - */ - @JsonProperty("prompt_tokens") - @ExcludeMissing - fun promptTokens(promptTokens: JsonField) = apply { - this.promptTokens = promptTokens - } - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } - - /** The total number of tokens in the input and output of the project logs event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) - - /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") - @ExcludeMissing - fun tokens(tokens: JsonField) = apply { this.tokens = tokens } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metrics = - Metrics( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - @JsonDeserialize(builder = Scores.Builder::class) - @NoAutoDetect - class Scores - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Scores{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplace.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplace.kt deleted file mode 100755 index 26089aee..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplace.kt +++ /dev/null @@ -1,1421 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.time.OffsetDateTime -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(builder = InsertProjectLogsEventReplace.Builder::class) -@NoAutoDetect -class InsertProjectLogsEventReplace -private constructor( - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanAttributes: JsonField, - private val id: JsonField, - private val created: JsonField, - private val _objectDelete: JsonField, - private val _isMerge: JsonField, - private val _parentId: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - fun input(): JsonValue = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. - */ - fun output(): JsonValue = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate while digging into - * analyses. However, we may later use these values to re-score outputs or fine-tune your - * models. - */ - fun expected(): JsonValue = expected - - /** The error that occurred, if any. */ - fun error(): JsonValue = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(): Optional = - Optional.ofNullable(spanAttributes.getNullable("span_attributes")) - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(): Optional = Optional.ofNullable(id.getNullable("id")) - - /** The timestamp the project logs event was created */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will not - * show up in subsequent fetches for this project logs - */ - fun _objectDelete(): Optional = - Optional.ofNullable(_objectDelete.getNullable("_object_delete")) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(): Optional = Optional.ofNullable(_isMerge.getNullable("_is_merge")) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(): Optional = Optional.ofNullable(_parentId.getNullable("_parent_id")) - - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - @JsonProperty("input") @ExcludeMissing fun _input() = input - - /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. - */ - @JsonProperty("output") @ExcludeMissing fun _output() = output - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate while digging into - * analyses. However, we may later use these values to re-score outputs or fine-tune your - * models. - */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected - - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata - - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - @JsonProperty("context") @ExcludeMissing fun _context() = context - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The timestamp the project logs event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will not - * show up in subsequent fetches for this project logs - */ - @JsonProperty("_object_delete") @ExcludeMissing fun __objectDelete() = _objectDelete - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same id - * in the DB. By default (or when set to `false`), the existing row is completely replaced by - * the new row. When set to `true`, the new row is deep-merged into the existing row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") @ExcludeMissing fun __isMerge() = _isMerge - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot be - * specified alongside `_is_merge=true`. Tracking hierarchical relationships are important for - * tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the parent - * row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What comes after - * foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the root span row - * `"abc"` will show up in the summary view. You can view the full trace hierarchy (in this - * case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") @ExcludeMissing fun __parentId() = _parentId - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): InsertProjectLogsEventReplace = apply { - if (!validated) { - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanAttributes().map { it.validate() } - id() - created() - _objectDelete() - _isMerge() - _parentId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is InsertProjectLogsEventReplace && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanAttributes == other.spanAttributes && - this.id == other.id && - this.created == other.created && - this._objectDelete == other._objectDelete && - this._isMerge == other._isMerge && - this._parentId == other._parentId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanAttributes, - id, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InsertProjectLogsEventReplace{input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanAttributes=$spanAttributes, id=$id, created=$created, _objectDelete=$_objectDelete, _isMerge=$_isMerge, _parentId=$_parentId, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() - private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanAttributes: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var _objectDelete: JsonField = JsonMissing.of() - private var _isMerge: JsonField = JsonMissing.of() - private var _parentId: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(insertProjectLogsEventReplace: InsertProjectLogsEventReplace) = apply { - this.input = insertProjectLogsEventReplace.input - this.output = insertProjectLogsEventReplace.output - this.expected = insertProjectLogsEventReplace.expected - this.error = insertProjectLogsEventReplace.error - this.scores = insertProjectLogsEventReplace.scores - this.metadata = insertProjectLogsEventReplace.metadata - this.tags = insertProjectLogsEventReplace.tags - this.metrics = insertProjectLogsEventReplace.metrics - this.context = insertProjectLogsEventReplace.context - this.spanAttributes = insertProjectLogsEventReplace.spanAttributes - this.id = insertProjectLogsEventReplace.id - this.created = insertProjectLogsEventReplace.created - this._objectDelete = insertProjectLogsEventReplace._objectDelete - this._isMerge = insertProjectLogsEventReplace._isMerge - this._parentId = insertProjectLogsEventReplace._parentId - additionalProperties(insertProjectLogsEventReplace.additionalProperties) - } - - /** - * The arguments that uniquely define a user input (an arbitrary, JSON serializable object). - */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } - - /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question. - */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } - - /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does - * not compare `output` to `expected` for you, since there are so many different ways to do - * that correctly. Instead, these values are just used to help you navigate while digging - * into analyses. However, we may later use these values to re-score outputs or fine-tune - * your models. - */ - @JsonProperty("expected") - @ExcludeMissing - fun expected(expected: JsonValue) = apply { this.expected = expected } - - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. - */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. - */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings - */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) - - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project - * logs event was produced - */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project - * logs event was produced - */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } - - /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event - */ - fun context(context: Context) = context(JsonField.of(context)) - - /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event - */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes - } - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - fun id(id: String) = id(JsonField.of(id)) - - /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you - */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** The timestamp the project logs event was created */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** The timestamp the project logs event was created */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will - * not show up in subsequent fetches for this project logs - */ - fun _objectDelete(_objectDelete: Boolean) = _objectDelete(JsonField.of(_objectDelete)) - - /** - * Pass `_object_delete=true` to mark the project logs event deleted. Deleted events will - * not show up in subsequent fetches for this project logs - */ - @JsonProperty("_object_delete") - @ExcludeMissing - fun _objectDelete(_objectDelete: JsonField) = apply { - this._objectDelete = _objectDelete - } - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - fun _isMerge(_isMerge: Boolean) = _isMerge(JsonField.of(_isMerge)) - - /** - * The `_is_merge` field controls how the row is merged with any existing row with the same - * id in the DB. By default (or when set to `false`), the existing row is completely - * replaced by the new row. When set to `true`, the new row is deep-merged into the existing - * row - * - * For example, say there is an existing row in the DB `{"id": "foo", "input": {"a": 5, "b": - * 10}}`. If we merge a new row as `{"_is_merge": true, "id": "foo", "input": {"b": 11, "c": - * 20}}`, the new row will be `{"id": "foo", "input": {"a": 5, "b": 11, "c": 20}}`. If we - * replace the new row as `{"id": "foo", "input": {"b": 11, "c": 20}}`, the new row will be - * `{"id": "foo", "input": {"b": 11, "c": 20}}` - */ - @JsonProperty("_is_merge") - @ExcludeMissing - fun _isMerge(_isMerge: JsonField) = apply { this._isMerge = _isMerge } - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - fun _parentId(_parentId: String) = _parentId(JsonField.of(_parentId)) - - /** - * Use the `_parent_id` field to create this row as a subspan of an existing row. It cannot - * be specified alongside `_is_merge=true`. Tracking hierarchical relationships are - * important for tracing (see the [guide](https://www.braintrust.dev/docs/guides/tracing) - * for full details). - * - * For example, say we have logged a row `{"id": "abc", "input": "foo", "output": "bar", - * "expected": "boo", "scores": {"correctness": 0.33}}`. We can create a sub-span of the - * parent row by logging `{"_parent_id": "abc", "id": "llm_call", "input": {"prompt": "What - * comes after foo?"}, "output": "bar", "metrics": {"tokens": 1}}`. In the webapp, only the - * root span row `"abc"` will show up in the summary view. You can view the full trace - * hierarchy (in this case, the `"llm_call"` row) by clicking on the "abc" row. - */ - @JsonProperty("_parent_id") - @ExcludeMissing - fun _parentId(_parentId: JsonField) = apply { this._parentId = _parentId } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): InsertProjectLogsEventReplace = - InsertProjectLogsEventReplace( - input, - output, - expected, - error, - scores, - metadata, - tags.map { it.toUnmodifiable() }, - metrics, - context, - spanAttributes, - id, - created, - _objectDelete, - _isMerge, - _parentId, - additionalProperties.toUnmodifiable(), - ) - } - - /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event - */ - @JsonDeserialize(builder = Context.Builder::class) - @NoAutoDetect - class Context - private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The function in code which created the project logs event */ - fun callerFunctionname(): Optional = - Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - - /** Name of the file in code where the project logs event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the project logs event was created */ - fun callerLineno(): Optional = - Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - - /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun _callerFunctionname() = callerFunctionname - - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename - - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var callerFunctionname: JsonField = JsonMissing.of() - private var callerFilename: JsonField = JsonMissing.of() - private var callerLineno: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) - } - - /** The function in code which created the project logs event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) - - /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") - @ExcludeMissing - fun callerFunctionname(callerFunctionname: JsonField) = apply { - this.callerFunctionname = callerFunctionname - } - - /** Name of the file in code where the project logs event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) - - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } - - /** Line of code where the project logs event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) - - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing - fun callerLineno(callerLineno: JsonField) = apply { - this.callerLineno = callerLineno - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Context = - Context( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings - */ - @JsonDeserialize(builder = Metadata.Builder::class) - @NoAutoDetect - class Metadata - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } - } - - /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced - */ - @JsonDeserialize(builder = Metrics.Builder::class) - @NoAutoDetect - class Metrics - private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * started - */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * finished - */ - fun end(): Optional = Optional.ofNullable(end.getNullable("end")) - - /** - * The number of tokens in the prompt used to generate the project logs event (only set if - * this is an LLM span) - */ - fun promptTokens(): Optional = - Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) - - /** The total number of tokens in the input and output of the project logs event. */ - fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * started - */ - @JsonProperty("start") @ExcludeMissing fun _start() = start - - /** - * A unix timestamp recording when the section of code which produced the project logs event - * finished - */ - @JsonProperty("end") @ExcludeMissing fun _end() = end - - /** - * The number of tokens in the prompt used to generate the project logs event (only set if - * this is an LLM span) - */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens - - /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens - - /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var start: JsonField = JsonMissing.of() - private var end: JsonField = JsonMissing.of() - private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() - private var tokens: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) - } - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event started - */ - fun start(start: Double) = start(JsonField.of(start)) - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event started - */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event finished - */ - fun end(end: Double) = end(JsonField.of(end)) - - /** - * A unix timestamp recording when the section of code which produced the project logs - * event finished - */ - @JsonProperty("end") - @ExcludeMissing - fun end(end: JsonField) = apply { this.end = end } - - /** - * The number of tokens in the prompt used to generate the project logs event (only set - * if this is an LLM span) - */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) - - /** - * The number of tokens in the prompt used to generate the project logs event (only set - * if this is an LLM span) - */ - @JsonProperty("prompt_tokens") - @ExcludeMissing - fun promptTokens(promptTokens: JsonField) = apply { - this.promptTokens = promptTokens - } - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) - - /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) - */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } - - /** The total number of tokens in the input and output of the project logs event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) - - /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") - @ExcludeMissing - fun tokens(tokens: JsonField) = apply { this.tokens = tokens } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Metrics = - Metrics( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties.toUnmodifiable(), - ) - } - } - - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. - */ - @JsonDeserialize(builder = Scores.Builder::class) - @NoAutoDetect - class Scores - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "Scores{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/MetricSummary.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/MetricSummary.kt index 5927af4c..a6233247 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/MetricSummary.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/MetricSummary.kt @@ -7,217 +7,319 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional /** Summary of a metric's performance */ -@JsonDeserialize(builder = MetricSummary.Builder::class) @NoAutoDetect class MetricSummary +@JsonCreator private constructor( - private val name: JsonField, - private val metric: JsonField, - private val unit: JsonField, - private val diff: JsonField, - private val improvements: JsonField, - private val regressions: JsonField, - private val additionalProperties: Map, + @JsonProperty("improvements") + @ExcludeMissing + private val improvements: JsonField = JsonMissing.of(), + @JsonProperty("metric") + @ExcludeMissing + private val metric: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("regressions") + @ExcludeMissing + private val regressions: JsonField = JsonMissing.of(), + @JsonProperty("unit") @ExcludeMissing private val unit: JsonField = JsonMissing.of(), + @JsonProperty("diff") @ExcludeMissing private val diff: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * Number of improvements in the metric + * + * @throws BraintrustInvalidDataException 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 improvements(): Long = improvements.getRequired("improvements") - private var hashCode: Int = 0 + /** + * Average metric across all examples + * + * @throws BraintrustInvalidDataException 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 metric(): Double = metric.getRequired("metric") - /** Name of the metric */ + /** + * Name of the metric + * + * @throws BraintrustInvalidDataException 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") - /** Average metric across all examples */ - fun metric(): Double = metric.getRequired("metric") + /** + * Number of regressions in the metric + * + * @throws BraintrustInvalidDataException 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 regressions(): Long = regressions.getRequired("regressions") - /** Unit label for the metric */ + /** + * Unit label for the metric + * + * @throws BraintrustInvalidDataException 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 unit(): String = unit.getRequired("unit") - /** Difference in metric between the current and comparison experiment */ + /** + * Difference in metric between the current and comparison experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun diff(): Optional = Optional.ofNullable(diff.getNullable("diff")) - /** Number of improvements in the metric */ - fun improvements(): Long = improvements.getRequired("improvements") - - /** Number of regressions in the metric */ - fun regressions(): Long = regressions.getRequired("regressions") - - /** Name of the metric */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Average metric across all examples */ - @JsonProperty("metric") @ExcludeMissing fun _metric() = metric - - /** Unit label for the metric */ - @JsonProperty("unit") @ExcludeMissing fun _unit() = unit - - /** Difference in metric between the current and comparison experiment */ - @JsonProperty("diff") @ExcludeMissing fun _diff() = diff - - /** Number of improvements in the metric */ - @JsonProperty("improvements") @ExcludeMissing fun _improvements() = improvements - - /** Number of regressions in the metric */ - @JsonProperty("regressions") @ExcludeMissing fun _regressions() = regressions + /** + * Returns the raw JSON value of [improvements]. + * + * Unlike [improvements], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("improvements") + @ExcludeMissing + fun _improvements(): JsonField = improvements + + /** + * Returns the raw JSON value of [metric]. + * + * Unlike [metric], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metric") @ExcludeMissing fun _metric(): JsonField = metric + + /** + * 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 [regressions]. + * + * Unlike [regressions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("regressions") @ExcludeMissing fun _regressions(): JsonField = regressions + + /** + * Returns the raw JSON value of [unit]. + * + * Unlike [unit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("unit") @ExcludeMissing fun _unit(): JsonField = unit + + /** + * Returns the raw JSON value of [diff]. + * + * Unlike [diff], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("diff") @ExcludeMissing fun _diff(): JsonField = diff @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): MetricSummary = apply { - if (!validated) { - name() - metric() - unit() - diff() - improvements() - regressions() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): MetricSummary = apply { + if (validated) { + return@apply } - return other is MetricSummary && - this.name == other.name && - this.metric == other.metric && - this.unit == other.unit && - this.diff == other.diff && - this.improvements == other.improvements && - this.regressions == other.regressions && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - metric, - unit, - diff, - improvements, - regressions, - additionalProperties, - ) - } - return hashCode + improvements() + metric() + name() + regressions() + unit() + diff() + validated = true } - override fun toString() = - "MetricSummary{name=$name, metric=$metric, unit=$unit, diff=$diff, improvements=$improvements, regressions=$regressions, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [MetricSummary]. + * + * The following fields are required: + * ```java + * .improvements() + * .metric() + * .name() + * .regressions() + * .unit() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [MetricSummary]. */ + class Builder internal constructor() { - private var name: JsonField = JsonMissing.of() - private var metric: JsonField = JsonMissing.of() - private var unit: JsonField = JsonMissing.of() + private var improvements: JsonField? = null + private var metric: JsonField? = null + private var name: JsonField? = null + private var regressions: JsonField? = null + private var unit: JsonField? = null private var diff: JsonField = JsonMissing.of() - private var improvements: JsonField = JsonMissing.of() - private var regressions: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metricSummary: MetricSummary) = apply { - this.name = metricSummary.name - this.metric = metricSummary.metric - this.unit = metricSummary.unit - this.diff = metricSummary.diff - this.improvements = metricSummary.improvements - this.regressions = metricSummary.regressions - additionalProperties(metricSummary.additionalProperties) + improvements = metricSummary.improvements + metric = metricSummary.metric + name = metricSummary.name + regressions = metricSummary.regressions + unit = metricSummary.unit + diff = metricSummary.diff + additionalProperties = metricSummary.additionalProperties.toMutableMap() } - /** Name of the metric */ - fun name(name: String) = name(JsonField.of(name)) + /** Number of improvements in the metric */ + fun improvements(improvements: Long) = improvements(JsonField.of(improvements)) - /** Name of the metric */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** + * Sets [Builder.improvements] to an arbitrary JSON value. + * + * You should usually call [Builder.improvements] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun improvements(improvements: JsonField) = apply { this.improvements = improvements } /** Average metric across all examples */ fun metric(metric: Double) = metric(JsonField.of(metric)) - /** Average metric across all examples */ - @JsonProperty("metric") - @ExcludeMissing + /** + * Sets [Builder.metric] to an arbitrary JSON value. + * + * You should usually call [Builder.metric] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun metric(metric: JsonField) = apply { this.metric = metric } + /** Name of the metric */ + 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 } + + /** Number of regressions in the metric */ + fun regressions(regressions: Long) = regressions(JsonField.of(regressions)) + + /** + * Sets [Builder.regressions] to an arbitrary JSON value. + * + * You should usually call [Builder.regressions] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun regressions(regressions: JsonField) = apply { this.regressions = regressions } + /** Unit label for the metric */ fun unit(unit: String) = unit(JsonField.of(unit)) - /** Unit label for the metric */ - @JsonProperty("unit") - @ExcludeMissing + /** + * Sets [Builder.unit] to an arbitrary JSON value. + * + * You should usually call [Builder.unit] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun unit(unit: JsonField) = apply { this.unit = unit } /** Difference in metric between the current and comparison experiment */ fun diff(diff: Double) = diff(JsonField.of(diff)) - /** Difference in metric between the current and comparison experiment */ - @JsonProperty("diff") - @ExcludeMissing + /** + * Sets [Builder.diff] to an arbitrary JSON value. + * + * You should usually call [Builder.diff] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun diff(diff: JsonField) = apply { this.diff = diff } - /** Number of improvements in the metric */ - fun improvements(improvements: Long) = improvements(JsonField.of(improvements)) - - /** Number of improvements in the metric */ - @JsonProperty("improvements") - @ExcludeMissing - fun improvements(improvements: JsonField) = apply { this.improvements = improvements } - - /** Number of regressions in the metric */ - fun regressions(regressions: Long) = regressions(JsonField.of(regressions)) - - /** Number of regressions in the metric */ - @JsonProperty("regressions") - @ExcludeMissing - fun regressions(regressions: JsonField) = apply { this.regressions = regressions } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [MetricSummary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .improvements() + * .metric() + * .name() + * .regressions() + * .unit() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): MetricSummary = MetricSummary( - name, - metric, - unit, + checkRequired("improvements", improvements), + checkRequired("metric", metric), + checkRequired("name", name), + checkRequired("regressions", regressions), + checkRequired("unit", unit), diff, - improvements, - regressions, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is MetricSummary && improvements == other.improvements && metric == other.metric && name == other.name && regressions == other.regressions && unit == other.unit && diff == other.diff && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(improvements, metric, name, regressions, unit, diff, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "MetricSummary{improvements=$improvements, metric=$metric, name=$name, regressions=$regressions, unit=$unit, diff=$diff, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ObjectReference.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ObjectReference.kt new file mode 100644 index 00000000..381f219f --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ObjectReference.kt @@ -0,0 +1,425 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Indicates the event was copied from another object. */ +@NoAutoDetect +class ObjectReference +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * ID of the original event. + * + * @throws BraintrustInvalidDataException 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") + + /** + * Transaction ID of the original event. + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") + + /** + * ID of the object the event is originating from. + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * Type of the object the event is originating from. + * + * @throws BraintrustInvalidDataException 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 objectType(): ObjectType = objectType.getRequired("object_type") + + /** + * Created timestamp of the original event. Used to help sort in the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * 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 [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): ObjectReference = apply { + if (validated) { + return@apply + } + + id() + _xactId() + objectId() + objectType() + created() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ObjectReference]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .objectId() + * .objectType() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ObjectReference]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var created: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(objectReference: ObjectReference) = apply { + id = objectReference.id + _xactId = objectReference._xactId + objectId = objectReference.objectId + objectType = objectReference.objectType + created = objectReference.created + additionalProperties = objectReference.additionalProperties.toMutableMap() + } + + /** ID of the original event. */ + 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 } + + /** Transaction ID of the original event. */ + fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) + + /** + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } + + /** ID of the object the event is originating from. */ + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } + + /** Type of the object the event is originating from. */ + fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [ObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { this.objectType = objectType } + + /** Created timestamp of the original event. Used to help sort in the UI */ + fun created(created: String?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + 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 [ObjectReference]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ObjectReference = + ObjectReference( + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + created, + additionalProperties.toImmutable(), + ) + } + + /** Type of the object the event is originating from. */ + class ObjectType @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 EXPERIMENT = of("experiment") + + @JvmField val DATASET = of("dataset") + + @JvmField val PROMPT = of("prompt") + + @JvmField val FUNCTION = of("function") + + @JvmField val PROMPT_SESSION = of("prompt_session") + + @JvmField val PROJECT_LOGS = of("project_logs") + + @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + } + + /** An enum containing [ObjectType]'s known values. */ + enum class Known { + EXPERIMENT, + DATASET, + PROMPT, + FUNCTION, + PROMPT_SESSION, + PROJECT_LOGS, + } + + /** + * An enum containing [ObjectType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ObjectType] 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 { + EXPERIMENT, + DATASET, + PROMPT, + FUNCTION, + PROMPT_SESSION, + PROJECT_LOGS, + /** + * An enum member indicating that [ObjectType] 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) { + EXPERIMENT -> Value.EXPERIMENT + DATASET -> Value.DATASET + PROMPT -> Value.PROMPT + FUNCTION -> Value.FUNCTION + PROMPT_SESSION -> Value.PROMPT_SESSION + PROJECT_LOGS -> Value.PROJECT_LOGS + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + EXPERIMENT -> Known.EXPERIMENT + DATASET -> Known.DATASET + PROMPT -> Known.PROMPT + FUNCTION -> Known.FUNCTION + PROMPT_SESSION -> Known.PROMPT_SESSION + PROJECT_LOGS -> Known.PROJECT_LOGS + else -> throw BraintrustInvalidDataException("Unknown ObjectType: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ObjectReference && id == other.id && _xactId == other._xactId && objectId == other.objectId && objectType == other.objectType && created == other.created && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, objectId, objectType, created, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ObjectReference{id=$id, _xactId=$_xactId, objectId=$objectId, objectType=$objectType, created=$created, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OnlineScoreConfig.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OnlineScoreConfig.kt index fcebfdc0..22191392 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OnlineScoreConfig.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OnlineScoreConfig.kt @@ -10,8 +10,11 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -26,122 +29,158 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = OnlineScoreConfig.Builder::class) @NoAutoDetect class OnlineScoreConfig +@JsonCreator private constructor( - private val samplingRate: JsonField, - private val scorers: JsonField>, - private val applyToRootSpan: JsonField, - private val applyToSpanNames: JsonField>, - private val additionalProperties: Map, + @JsonProperty("sampling_rate") + @ExcludeMissing + private val samplingRate: JsonField = JsonMissing.of(), + @JsonProperty("scorers") + @ExcludeMissing + private val scorers: JsonField> = JsonMissing.of(), + @JsonProperty("apply_to_root_span") + @ExcludeMissing + private val applyToRootSpan: JsonField = JsonMissing.of(), + @JsonProperty("apply_to_span_names") + @ExcludeMissing + private val applyToSpanNames: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** The sampling rate for online scoring */ + /** + * The sampling rate for online scoring + * + * @throws BraintrustInvalidDataException 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 samplingRate(): Double = samplingRate.getRequired("sampling_rate") - /** The list of scorers to use for online scoring */ + /** + * The list of scorers to use for online scoring + * + * @throws BraintrustInvalidDataException 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 scorers(): List = scorers.getRequired("scorers") - /** Whether to trigger online scoring on the root span of each trace */ + /** + * Whether to trigger online scoring on the root span of each trace + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun applyToRootSpan(): Optional = Optional.ofNullable(applyToRootSpan.getNullable("apply_to_root_span")) - /** Trigger online scoring on any spans with a name in this list */ + /** + * Trigger online scoring on any spans with a name in this list + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun applyToSpanNames(): Optional> = Optional.ofNullable(applyToSpanNames.getNullable("apply_to_span_names")) - /** The sampling rate for online scoring */ - @JsonProperty("sampling_rate") @ExcludeMissing fun _samplingRate() = samplingRate - - /** The list of scorers to use for online scoring */ - @JsonProperty("scorers") @ExcludeMissing fun _scorers() = scorers - - /** Whether to trigger online scoring on the root span of each trace */ - @JsonProperty("apply_to_root_span") @ExcludeMissing fun _applyToRootSpan() = applyToRootSpan - - /** Trigger online scoring on any spans with a name in this list */ - @JsonProperty("apply_to_span_names") @ExcludeMissing fun _applyToSpanNames() = applyToSpanNames + /** + * Returns the raw JSON value of [samplingRate]. + * + * Unlike [samplingRate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sampling_rate") + @ExcludeMissing + fun _samplingRate(): JsonField = samplingRate + + /** + * Returns the raw JSON value of [scorers]. + * + * Unlike [scorers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scorers") @ExcludeMissing fun _scorers(): JsonField> = scorers + + /** + * Returns the raw JSON value of [applyToRootSpan]. + * + * Unlike [applyToRootSpan], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("apply_to_root_span") + @ExcludeMissing + fun _applyToRootSpan(): JsonField = applyToRootSpan + + /** + * Returns the raw JSON value of [applyToSpanNames]. + * + * Unlike [applyToSpanNames], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("apply_to_span_names") + @ExcludeMissing + fun _applyToSpanNames(): JsonField> = applyToSpanNames @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): OnlineScoreConfig = apply { - if (!validated) { - samplingRate() - scorers() - applyToRootSpan() - applyToSpanNames() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): OnlineScoreConfig = apply { + if (validated) { + return@apply } - return other is OnlineScoreConfig && - this.samplingRate == other.samplingRate && - this.scorers == other.scorers && - this.applyToRootSpan == other.applyToRootSpan && - this.applyToSpanNames == other.applyToSpanNames && - this.additionalProperties == other.additionalProperties + samplingRate() + scorers().forEach { it.validate() } + applyToRootSpan() + applyToSpanNames() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - samplingRate, - scorers, - applyToRootSpan, - applyToSpanNames, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "OnlineScoreConfig{samplingRate=$samplingRate, scorers=$scorers, applyToRootSpan=$applyToRootSpan, applyToSpanNames=$applyToSpanNames, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [OnlineScoreConfig]. + * + * The following fields are required: + * ```java + * .samplingRate() + * .scorers() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [OnlineScoreConfig]. */ + class Builder internal constructor() { - private var samplingRate: JsonField = JsonMissing.of() - private var scorers: JsonField> = JsonMissing.of() + private var samplingRate: JsonField? = null + private var scorers: JsonField>? = null private var applyToRootSpan: JsonField = JsonMissing.of() - private var applyToSpanNames: JsonField> = JsonMissing.of() + private var applyToSpanNames: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(onlineScoreConfig: OnlineScoreConfig) = apply { - this.samplingRate = onlineScoreConfig.samplingRate - this.scorers = onlineScoreConfig.scorers - this.applyToRootSpan = onlineScoreConfig.applyToRootSpan - this.applyToSpanNames = onlineScoreConfig.applyToSpanNames - additionalProperties(onlineScoreConfig.additionalProperties) + samplingRate = onlineScoreConfig.samplingRate + scorers = onlineScoreConfig.scorers.map { it.toMutableList() } + applyToRootSpan = onlineScoreConfig.applyToRootSpan + applyToSpanNames = onlineScoreConfig.applyToSpanNames.map { it.toMutableList() } + additionalProperties = onlineScoreConfig.additionalProperties.toMutableMap() } /** The sampling rate for online scoring */ fun samplingRate(samplingRate: Double) = samplingRate(JsonField.of(samplingRate)) - /** The sampling rate for online scoring */ - @JsonProperty("sampling_rate") - @ExcludeMissing + /** + * Sets [Builder.samplingRate] to an arbitrary JSON value. + * + * You should usually call [Builder.samplingRate] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun samplingRate(samplingRate: JsonField) = apply { this.samplingRate = samplingRate } @@ -149,54 +188,131 @@ private constructor( /** The list of scorers to use for online scoring */ fun scorers(scorers: List) = scorers(JsonField.of(scorers)) - /** The list of scorers to use for online scoring */ - @JsonProperty("scorers") - @ExcludeMissing - fun scorers(scorers: JsonField>) = apply { this.scorers = scorers } + /** + * Sets [Builder.scorers] to an arbitrary JSON value. + * + * You should usually call [Builder.scorers] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun scorers(scorers: JsonField>) = apply { + this.scorers = scorers.map { it.toMutableList() } + } - /** Whether to trigger online scoring on the root span of each trace */ - fun applyToRootSpan(applyToRootSpan: Boolean) = - applyToRootSpan(JsonField.of(applyToRootSpan)) + /** + * Adds a single [Scorer] to [scorers]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addScorer(scorer: Scorer) = apply { + scorers = + (scorers ?: JsonField.of(mutableListOf())).also { + checkKnown("scorers", it).add(scorer) + } + } + + /** Alias for calling [addScorer] with `Scorer.ofFunction(function)`. */ + fun addScorer(function: Scorer.Function) = addScorer(Scorer.ofFunction(function)) + + /** Alias for calling [addScorer] with `Scorer.ofGlobal(global)`. */ + fun addScorer(global: Scorer.Global) = addScorer(Scorer.ofGlobal(global)) /** Whether to trigger online scoring on the root span of each trace */ - @JsonProperty("apply_to_root_span") - @ExcludeMissing + fun applyToRootSpan(applyToRootSpan: Boolean?) = + applyToRootSpan(JsonField.ofNullable(applyToRootSpan)) + + /** + * Alias for [Builder.applyToRootSpan]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun applyToRootSpan(applyToRootSpan: Boolean) = applyToRootSpan(applyToRootSpan as Boolean?) + + /** Alias for calling [Builder.applyToRootSpan] with `applyToRootSpan.orElse(null)`. */ + fun applyToRootSpan(applyToRootSpan: Optional) = + applyToRootSpan(applyToRootSpan.getOrNull()) + + /** + * Sets [Builder.applyToRootSpan] to an arbitrary JSON value. + * + * You should usually call [Builder.applyToRootSpan] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun applyToRootSpan(applyToRootSpan: JsonField) = apply { this.applyToRootSpan = applyToRootSpan } /** Trigger online scoring on any spans with a name in this list */ - fun applyToSpanNames(applyToSpanNames: List) = - applyToSpanNames(JsonField.of(applyToSpanNames)) - - /** Trigger online scoring on any spans with a name in this list */ - @JsonProperty("apply_to_span_names") - @ExcludeMissing + fun applyToSpanNames(applyToSpanNames: List?) = + applyToSpanNames(JsonField.ofNullable(applyToSpanNames)) + + /** Alias for calling [Builder.applyToSpanNames] with `applyToSpanNames.orElse(null)`. */ + fun applyToSpanNames(applyToSpanNames: Optional>) = + applyToSpanNames(applyToSpanNames.getOrNull()) + + /** + * Sets [Builder.applyToSpanNames] to an arbitrary JSON value. + * + * You should usually call [Builder.applyToSpanNames] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun applyToSpanNames(applyToSpanNames: JsonField>) = apply { - this.applyToSpanNames = applyToSpanNames + this.applyToSpanNames = applyToSpanNames.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [applyToSpanNames]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addApplyToSpanName(applyToSpanName: String) = apply { + applyToSpanNames = + (applyToSpanNames ?: JsonField.of(mutableListOf())).also { + checkKnown("applyToSpanNames", it).add(applyToSpanName) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [OnlineScoreConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .samplingRate() + * .scorers() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): OnlineScoreConfig = OnlineScoreConfig( - samplingRate, - scorers.map { it.toUnmodifiable() }, + checkRequired("samplingRate", samplingRate), + checkRequired("scorers", scorers).map { it.toImmutable() }, applyToRootSpan, - applyToSpanNames.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + (applyToSpanNames ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } @@ -209,8 +325,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun function(): Optional = Optional.ofNullable(function) fun global(): Optional = Optional.ofNullable(global) @@ -233,15 +347,25 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): Scorer = apply { - if (!validated) { - if (function == null && global == null) { - throw BraintrustInvalidDataException("Unknown Scorer: $_json") - } - function?.validate() - global?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitFunction(function: Function) { + function.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -249,21 +373,18 @@ private constructor( return true } - return other is Scorer && this.function == other.function && this.global == other.global + return /* spotless:off */ other is Scorer && function == other.function && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(function, global) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(function, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { function != null -> "Scorer{function=$function}" global != null -> "Scorer{global=$global}" _json != null -> "Scorer{_unknown=$_json}" else -> throw IllegalStateException("Invalid Scorer") } - } companion object { @@ -272,21 +393,33 @@ private constructor( @JvmStatic fun ofGlobal(global: Global) = Scorer(global = global) } + /** An interface that defines how to map each variant of [Scorer] to a value of type [T]. */ interface Visitor { fun visitFunction(function: Function): T fun visitGlobal(global: Global): T + /** + * Maps an unknown variant of [Scorer] to a value of type [T]. + * + * An instance of [Scorer] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Scorer: $json") } } - class Deserializer : BaseDeserializer(Scorer::class) { + internal class Deserializer : BaseDeserializer(Scorer::class) { override fun ObjectCodec.deserialize(node: JsonNode): Scorer { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Scorer(function = it, _json = json) @@ -300,12 +433,12 @@ private constructor( } } - class Serializer : BaseSerializer(Scorer::class) { + internal class Serializer : BaseSerializer(Scorer::class) { override fun serialize( value: Scorer, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.function != null -> generator.writeObject(value.function) @@ -316,105 +449,123 @@ private constructor( } } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val type: JsonField, - private val id: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") + @ExcludeMissing + private val id: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun id(): String = id.getRequired("id") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - type() - id() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.type == other.type && - this.id == other.id && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - id, - additionalProperties, - ) - } - return hashCode + id() + type() + validated = true } - override fun toString() = - "Function{type=$type, id=$id, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.type = function.type - this.id = function.id - additionalProperties(function.additionalProperties) + id = function.id + type = function.type + additionalProperties = function.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun id(id: String) = id(JsonField.of(id)) - @JsonProperty("id") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -422,165 +573,267 @@ private constructor( 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( - type, - id, - additionalProperties.toUnmodifiable(), + checkRequired("id", id), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val FUNCTION = Type(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { FUNCTION, + /** + * An enum member indicating that [Type] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && id == other.id && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{id=$id, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") + /** + * 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 - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -588,64 +841,165 @@ private constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OnlineScoreConfig && samplingRate == other.samplingRate && scorers == other.scorers && applyToRootSpan == other.applyToRootSpan && applyToSpanNames == other.applyToSpanNames && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(samplingRate, scorers, applyToRootSpan, applyToSpanNames, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "OnlineScoreConfig{samplingRate=$samplingRate, scorers=$scorers, applyToRootSpan=$applyToRootSpan, applyToSpanNames=$applyToSpanNames, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Organization.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Organization.kt index 44c9b609..532da10b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Organization.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Organization.kt @@ -7,224 +7,368 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Organization.Builder::class) @NoAutoDetect class Organization +@JsonCreator private constructor( - private val id: JsonField, - private val name: JsonField, - private val apiUrl: JsonField, - private val isUniversalApi: JsonField, - private val proxyUrl: JsonField, - private val realtimeUrl: JsonField, - private val created: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("api_url") + @ExcludeMissing + private val apiUrl: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("is_universal_api") + @ExcludeMissing + private val isUniversalApi: JsonField = JsonMissing.of(), + @JsonProperty("proxy_url") + @ExcludeMissing + private val proxyUrl: JsonField = JsonMissing.of(), + @JsonProperty("realtime_url") + @ExcludeMissing + private val realtimeUrl: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the organization */ + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException 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") - /** Name of the organization */ + /** + * Name of the organization + * + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun apiUrl(): Optional = Optional.ofNullable(apiUrl.getNullable("api_url")) + /** + * Date of organization creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun isUniversalApi(): Optional = Optional.ofNullable(isUniversalApi.getNullable("is_universal_api")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun proxyUrl(): Optional = Optional.ofNullable(proxyUrl.getNullable("proxy_url")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun realtimeUrl(): Optional = Optional.ofNullable(realtimeUrl.getNullable("realtime_url")) - /** Date of organization creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** Unique identifier for the organization */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Name of the organization */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonProperty("api_url") @ExcludeMissing fun _apiUrl() = apiUrl - - @JsonProperty("is_universal_api") @ExcludeMissing fun _isUniversalApi() = isUniversalApi - - @JsonProperty("proxy_url") @ExcludeMissing fun _proxyUrl() = proxyUrl - - @JsonProperty("realtime_url") @ExcludeMissing fun _realtimeUrl() = realtimeUrl - - /** Date of organization creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 [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 [apiUrl]. + * + * Unlike [apiUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("api_url") @ExcludeMissing fun _apiUrl(): JsonField = apiUrl + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [isUniversalApi]. + * + * Unlike [isUniversalApi], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("is_universal_api") + @ExcludeMissing + fun _isUniversalApi(): JsonField = isUniversalApi + + /** + * Returns the raw JSON value of [proxyUrl]. + * + * Unlike [proxyUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("proxy_url") @ExcludeMissing fun _proxyUrl(): JsonField = proxyUrl + + /** + * Returns the raw JSON value of [realtimeUrl]. + * + * Unlike [realtimeUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("realtime_url") + @ExcludeMissing + fun _realtimeUrl(): JsonField = realtimeUrl @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Organization = apply { - if (!validated) { - id() - name() - apiUrl() - isUniversalApi() - proxyUrl() - realtimeUrl() - created() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Organization = apply { + if (validated) { + return@apply } - return other is Organization && - this.id == other.id && - this.name == other.name && - this.apiUrl == other.apiUrl && - this.isUniversalApi == other.isUniversalApi && - this.proxyUrl == other.proxyUrl && - this.realtimeUrl == other.realtimeUrl && - this.created == other.created && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - name, - apiUrl, - isUniversalApi, - proxyUrl, - realtimeUrl, - created, - additionalProperties, - ) - } - return hashCode + id() + name() + apiUrl() + created() + isUniversalApi() + proxyUrl() + realtimeUrl() + validated = true } - override fun toString() = - "Organization{id=$id, name=$name, apiUrl=$apiUrl, isUniversalApi=$isUniversalApi, proxyUrl=$proxyUrl, realtimeUrl=$realtimeUrl, created=$created, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Organization]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Organization]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null private var apiUrl: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() private var isUniversalApi: JsonField = JsonMissing.of() private var proxyUrl: JsonField = JsonMissing.of() private var realtimeUrl: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(organization: Organization) = apply { - this.id = organization.id - this.name = organization.name - this.apiUrl = organization.apiUrl - this.isUniversalApi = organization.isUniversalApi - this.proxyUrl = organization.proxyUrl - this.realtimeUrl = organization.realtimeUrl - this.created = organization.created - additionalProperties(organization.additionalProperties) + id = organization.id + name = organization.name + apiUrl = organization.apiUrl + created = organization.created + isUniversalApi = organization.isUniversalApi + proxyUrl = organization.proxyUrl + realtimeUrl = organization.realtimeUrl + additionalProperties = organization.additionalProperties.toMutableMap() } /** Unique identifier for the organization */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the organization */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } /** Name of the organization */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the organization */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } - fun apiUrl(apiUrl: String) = apiUrl(JsonField.of(apiUrl)) + fun apiUrl(apiUrl: String?) = apiUrl(JsonField.ofNullable(apiUrl)) + + /** Alias for calling [Builder.apiUrl] with `apiUrl.orElse(null)`. */ + fun apiUrl(apiUrl: Optional) = apiUrl(apiUrl.getOrNull()) - @JsonProperty("api_url") - @ExcludeMissing + /** + * Sets [Builder.apiUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.apiUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun apiUrl(apiUrl: JsonField) = apply { this.apiUrl = apiUrl } - fun isUniversalApi(isUniversalApi: Boolean) = isUniversalApi(JsonField.of(isUniversalApi)) + /** Date of organization creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } - @JsonProperty("is_universal_api") - @ExcludeMissing + fun isUniversalApi(isUniversalApi: Boolean?) = + isUniversalApi(JsonField.ofNullable(isUniversalApi)) + + /** + * Alias for [Builder.isUniversalApi]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isUniversalApi(isUniversalApi: Boolean) = isUniversalApi(isUniversalApi as Boolean?) + + /** Alias for calling [Builder.isUniversalApi] with `isUniversalApi.orElse(null)`. */ + fun isUniversalApi(isUniversalApi: Optional) = + isUniversalApi(isUniversalApi.getOrNull()) + + /** + * Sets [Builder.isUniversalApi] to an arbitrary JSON value. + * + * You should usually call [Builder.isUniversalApi] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun isUniversalApi(isUniversalApi: JsonField) = apply { this.isUniversalApi = isUniversalApi } - fun proxyUrl(proxyUrl: String) = proxyUrl(JsonField.of(proxyUrl)) + fun proxyUrl(proxyUrl: String?) = proxyUrl(JsonField.ofNullable(proxyUrl)) - @JsonProperty("proxy_url") - @ExcludeMissing - fun proxyUrl(proxyUrl: JsonField) = apply { this.proxyUrl = proxyUrl } + /** Alias for calling [Builder.proxyUrl] with `proxyUrl.orElse(null)`. */ + fun proxyUrl(proxyUrl: Optional) = proxyUrl(proxyUrl.getOrNull()) - fun realtimeUrl(realtimeUrl: String) = realtimeUrl(JsonField.of(realtimeUrl)) + /** + * Sets [Builder.proxyUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.proxyUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun proxyUrl(proxyUrl: JsonField) = apply { this.proxyUrl = proxyUrl } - @JsonProperty("realtime_url") - @ExcludeMissing - fun realtimeUrl(realtimeUrl: JsonField) = apply { this.realtimeUrl = realtimeUrl } + fun realtimeUrl(realtimeUrl: String?) = realtimeUrl(JsonField.ofNullable(realtimeUrl)) - /** Date of organization creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** Alias for calling [Builder.realtimeUrl] with `realtimeUrl.orElse(null)`. */ + fun realtimeUrl(realtimeUrl: Optional) = realtimeUrl(realtimeUrl.getOrNull()) - /** Date of organization creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * Sets [Builder.realtimeUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.realtimeUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun realtimeUrl(realtimeUrl: JsonField) = apply { this.realtimeUrl = realtimeUrl } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Organization]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Organization = Organization( - id, - name, + checkRequired("id", id), + checkRequired("name", name), apiUrl, + created, isUniversalApi, proxyUrl, realtimeUrl, - created, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Organization && id == other.id && name == other.name && apiUrl == other.apiUrl && created == other.created && isUniversalApi == other.isUniversalApi && proxyUrl == other.proxyUrl && realtimeUrl == other.realtimeUrl && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, apiUrl, created, isUniversalApi, proxyUrl, realtimeUrl, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Organization{id=$id, name=$name, apiUrl=$apiUrl, created=$created, isUniversalApi=$isUniversalApi, proxyUrl=$proxyUrl, realtimeUrl=$realtimeUrl, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationDeleteParams.kt index 2a32949b..a6d936fa 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete an organization object by its id */ class OrganizationDeleteParams -constructor( +private constructor( private val organizationId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Organization id */ fun organizationId(): String = organizationId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,147 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is OrganizationDeleteParams && - this.organizationId == other.organizationId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - organizationId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "OrganizationDeleteParams{organizationId=$organizationId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [OrganizationDeleteParams]. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [OrganizationDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var organizationId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(organizationDeleteParams: OrganizationDeleteParams) = apply { - this.organizationId = organizationDeleteParams.organizationId - additionalQueryParams(organizationDeleteParams.additionalQueryParams) - additionalHeaders(organizationDeleteParams.additionalHeaders) - additionalBodyProperties(organizationDeleteParams.additionalBodyProperties) + organizationId = organizationDeleteParams.organizationId + additionalHeaders = organizationDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = organizationDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + organizationDeleteParams.additionalBodyProperties.toMutableMap() } /** Organization id */ fun organizationId(organizationId: String) = apply { this.organizationId = organizationId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +193,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [OrganizationDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): OrganizationDeleteParams = OrganizationDeleteParams( - checkNotNull(organizationId) { "`organizationId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("organizationId", organizationId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OrganizationDeleteParams && organizationId == other.organizationId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(organizationId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "OrganizationDeleteParams{organizationId=$organizationId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPage.kt index ed6d9bd9..6683eed2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.OrganizationService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all organizations. The organizations are sorted by creation date, with the most + * recently-created organizations coming first + */ class OrganizationListPage private constructor( private val organizationsService: OrganizationService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is OrganizationListPage && - this.organizationsService == other.organizationsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is OrganizationListPage && organizationsService == other.organizationsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - organizationsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(organizationsService, params, response) /* spotless:on */ override fun toString() = "OrganizationListPage{organizationsService=$organizationsService, params=$params, response=$response}" @@ -89,25 +86,20 @@ private constructor( fun of( organizationsService: OrganizationService, params: OrganizationListParams, - response: Response - ) = - OrganizationListPage( - organizationsService, - params, - response, - ) + response: Response, + ) = OrganizationListPage(organizationsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -117,11 +109,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -131,20 +127,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "OrganizationListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [OrganizationListPage]. */ @JvmStatic fun builder() = Builder() } @@ -161,22 +154,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: OrganizationListPage, - ) : Iterable { + class AutoPager(private val firstPage: OrganizationListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -185,7 +178,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPageAsync.kt index 5dc12993..0c6503ba 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.OrganizationServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all organizations. The organizations are sorted by creation date, with the most + * recently-created organizations coming first + */ class OrganizationListPageAsync private constructor( private val organizationsService: OrganizationServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is OrganizationListPageAsync && - this.organizationsService == other.organizationsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is OrganizationListPageAsync && organizationsService == other.organizationsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - organizationsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(organizationsService, params, response) /* spotless:on */ override fun toString() = "OrganizationListPageAsync{organizationsService=$organizationsService, params=$params, response=$response}" @@ -92,25 +88,20 @@ private constructor( fun of( organizationsService: OrganizationServiceAsync, params: OrganizationListParams, - response: Response - ) = - OrganizationListPageAsync( - organizationsService, - params, - response, - ) + response: Response, + ) = OrganizationListPageAsync(organizationsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +111,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +129,20 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "OrganizationListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of + * [OrganizationListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +159,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: OrganizationListPageAsync, - ) { + class AutoPager(private val firstPage: OrganizationListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Organization) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +188,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListParams.kt index 76ac2962..ee4d5674 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,103 +20,112 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all organizations. The organizations are sorted by creation date, with the most + * recently-created organizations coming first + */ class OrganizationListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val orgName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is OrganizationListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "OrganizationListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): OrganizationListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [OrganizationListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [OrganizationListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null private var limit: Long? = null private var orgName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(organizationListParams: OrganizationListParams) = apply { - this.endingBefore = organizationListParams.endingBefore - this.ids = organizationListParams.ids - this.limit = organizationListParams.limit - this.orgName = organizationListParams.orgName - this.startingAfter = organizationListParams.startingAfter - additionalQueryParams(organizationListParams.additionalQueryParams) - additionalHeaders(organizationListParams.additionalHeaders) + endingBefore = organizationListParams.endingBefore + ids = organizationListParams.ids + limit = organizationListParams.limit + orgName = organizationListParams.orgName + startingAfter = organizationListParams.startingAfter + additionalHeaders = organizationListParams.additionalHeaders.toBuilder() + additionalQueryParams = organizationListParams.additionalQueryParams.toBuilder() } /** @@ -125,31 +135,44 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** * Pagination cursor id. @@ -158,48 +181,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + 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 putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [OrganizationListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): OrganizationListParams = OrganizationListParams( endingBefore, @@ -207,11 +297,15 @@ constructor( limit, orgName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -221,8 +315,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -245,35 +337,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -282,21 +362,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -308,12 +399,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -324,4 +415,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OrganizationListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "OrganizationListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParams.kt index b97ce9e2..11ffafd2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParams.kt @@ -3,145 +3,261 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** Modify organization membership */ class OrganizationMemberUpdateParams -constructor( - private val inviteUsers: InviteUsers?, - private val orgId: String?, - private val orgName: String?, - private val removeUsers: RemoveUsers?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun inviteUsers(): Optional = Optional.ofNullable(inviteUsers) - - fun orgId(): Optional = Optional.ofNullable(orgId) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - fun removeUsers(): Optional = Optional.ofNullable(removeUsers) - - @JvmSynthetic - internal fun getBody(): OrganizationMemberUpdateBody { - return OrganizationMemberUpdateBody( - inviteUsers, - orgId, - orgName, - removeUsers, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Users to invite to the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inviteUsers(): Optional = body.inviteUsers() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, or in case you want to explicitly assert the + * organization you are modifying, you may specify the id of the organization. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgId(): Optional = body.orgId() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, or in case you want to explicitly assert the + * organization you are modifying, you may specify the name of the organization. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * Users to remove from the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun removeUsers(): Optional = body.removeUsers() + + /** + * Returns the raw JSON value of [inviteUsers]. + * + * Unlike [inviteUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _inviteUsers(): JsonField = body._inviteUsers() + + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgId(): JsonField = body._orgId() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + /** + * Returns the raw JSON value of [removeUsers]. + * + * Unlike [removeUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _removeUsers(): JsonField = body._removeUsers() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = OrganizationMemberUpdateBody.Builder::class) @NoAutoDetect - class OrganizationMemberUpdateBody - internal constructor( - private val inviteUsers: InviteUsers?, - private val orgId: String?, - private val orgName: String?, - private val removeUsers: RemoveUsers?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("invite_users") + @ExcludeMissing + private val inviteUsers: JsonField = JsonMissing.of(), + @JsonProperty("org_id") + @ExcludeMissing + private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonProperty("remove_users") + @ExcludeMissing + private val removeUsers: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Users to invite to the organization */ - @JsonProperty("invite_users") fun inviteUsers(): InviteUsers? = inviteUsers + /** + * Users to invite to the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun inviteUsers(): Optional = + Optional.ofNullable(inviteUsers.getNullable("invite_users")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, or in case you want to explicitly assert * the organization you are modifying, you may specify the id of the organization. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("org_id") fun orgId(): String? = orgId + fun orgId(): Optional = Optional.ofNullable(orgId.getNullable("org_id")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, or in case you want to explicitly assert * the organization you are modifying, you may specify the name of the organization. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("org_name") fun orgName(): String? = orgName + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) - /** Users to remove from the organization */ - @JsonProperty("remove_users") fun removeUsers(): RemoveUsers? = removeUsers + /** + * Users to remove from the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeUsers(): Optional = + Optional.ofNullable(removeUsers.getNullable("remove_users")) + + /** + * Returns the raw JSON value of [inviteUsers]. + * + * Unlike [inviteUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("invite_users") + @ExcludeMissing + fun _inviteUsers(): JsonField = inviteUsers + + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName + + /** + * Returns the raw JSON value of [removeUsers]. + * + * Unlike [removeUsers], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("remove_users") + @ExcludeMissing + fun _removeUsers(): JsonField = removeUsers @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is OrganizationMemberUpdateBody && - this.inviteUsers == other.inviteUsers && - this.orgId == other.orgId && - this.orgName == other.orgName && - this.removeUsers == other.removeUsers && - this.additionalProperties == other.additionalProperties + inviteUsers().ifPresent { it.validate() } + orgId() + orgName() + removeUsers().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - inviteUsers, - orgId, - orgName, - removeUsers, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "OrganizationMemberUpdateBody{inviteUsers=$inviteUsers, orgId=$orgId, orgName=$orgName, removeUsers=$removeUsers, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var inviteUsers: InviteUsers? = null - private var orgId: String? = null - private var orgName: String? = null - private var removeUsers: RemoveUsers? = null + private var inviteUsers: JsonField = JsonMissing.of() + private var orgId: JsonField = JsonMissing.of() + private var orgName: JsonField = JsonMissing.of() + private var removeUsers: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(organizationMemberUpdateBody: OrganizationMemberUpdateBody) = apply { - this.inviteUsers = organizationMemberUpdateBody.inviteUsers - this.orgId = organizationMemberUpdateBody.orgId - this.orgName = organizationMemberUpdateBody.orgName - this.removeUsers = organizationMemberUpdateBody.removeUsers - additionalProperties(organizationMemberUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + inviteUsers = body.inviteUsers + orgId = body.orgId + orgName = body.orgName + removeUsers = body.removeUsers + additionalProperties = body.additionalProperties.toMutableMap() } /** Users to invite to the organization */ - @JsonProperty("invite_users") - fun inviteUsers(inviteUsers: InviteUsers) = apply { this.inviteUsers = inviteUsers } + fun inviteUsers(inviteUsers: InviteUsers?) = + inviteUsers(JsonField.ofNullable(inviteUsers)) + + /** Alias for calling [Builder.inviteUsers] with `inviteUsers.orElse(null)`. */ + fun inviteUsers(inviteUsers: Optional) = + inviteUsers(inviteUsers.getOrNull()) + + /** + * Sets [Builder.inviteUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.inviteUsers] with a well-typed [InviteUsers] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inviteUsers(inviteUsers: JsonField) = apply { + this.inviteUsers = inviteUsers + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that @@ -149,7 +265,19 @@ constructor( * assert the organization you are modifying, you may specify the id of the * organization. */ - @JsonProperty("org_id") fun orgId(orgId: String) = apply { this.orgId = orgId } + fun orgId(orgId: String?) = orgId(JsonField.ofNullable(orgId)) + + /** Alias for calling [Builder.orgId] with `orgId.orElse(null)`. */ + fun orgId(orgId: Optional) = orgId(orgId.getOrNull()) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgId(orgId: JsonField) = apply { this.orgId = orgId } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that @@ -157,449 +285,936 @@ constructor( * assert the organization you are modifying, you may specify the name of the * organization. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } /** Users to remove from the organization */ - @JsonProperty("remove_users") - fun removeUsers(removeUsers: RemoveUsers) = apply { this.removeUsers = removeUsers } + fun removeUsers(removeUsers: RemoveUsers?) = + removeUsers(JsonField.ofNullable(removeUsers)) + + /** Alias for calling [Builder.removeUsers] with `removeUsers.orElse(null)`. */ + fun removeUsers(removeUsers: Optional) = + removeUsers(removeUsers.getOrNull()) + + /** + * Sets [Builder.removeUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.removeUsers] with a well-typed [RemoveUsers] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun removeUsers(removeUsers: JsonField) = apply { + this.removeUsers = removeUsers + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): OrganizationMemberUpdateBody = - OrganizationMemberUpdateBody( - inviteUsers, - orgId, - orgName, - removeUsers, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = + Body(inviteUsers, orgId, orgName, removeUsers, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && inviteUsers == other.inviteUsers && orgId == other.orgId && orgName == other.orgName && removeUsers == other.removeUsers && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is OrganizationMemberUpdateParams && - this.inviteUsers == other.inviteUsers && - this.orgId == other.orgId && - this.orgName == other.orgName && - this.removeUsers == other.removeUsers && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(inviteUsers, orgId, orgName, removeUsers, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - inviteUsers, - orgId, - orgName, - removeUsers, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "OrganizationMemberUpdateParams{inviteUsers=$inviteUsers, orgId=$orgId, orgName=$orgName, removeUsers=$removeUsers, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{inviteUsers=$inviteUsers, orgId=$orgId, orgName=$orgName, removeUsers=$removeUsers, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): OrganizationMemberUpdateParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of + * [OrganizationMemberUpdateParams]. + */ @JvmStatic fun builder() = Builder() } + /** A builder for [OrganizationMemberUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var inviteUsers: InviteUsers? = null - private var orgId: String? = null - private var orgName: String? = null - private var removeUsers: RemoveUsers? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(organizationMemberUpdateParams: OrganizationMemberUpdateParams) = apply { - this.inviteUsers = organizationMemberUpdateParams.inviteUsers - this.orgId = organizationMemberUpdateParams.orgId - this.orgName = organizationMemberUpdateParams.orgName - this.removeUsers = organizationMemberUpdateParams.removeUsers - additionalQueryParams(organizationMemberUpdateParams.additionalQueryParams) - additionalHeaders(organizationMemberUpdateParams.additionalHeaders) - additionalBodyProperties(organizationMemberUpdateParams.additionalBodyProperties) + body = organizationMemberUpdateParams.body.toBuilder() + additionalHeaders = organizationMemberUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = organizationMemberUpdateParams.additionalQueryParams.toBuilder() } /** Users to invite to the organization */ - fun inviteUsers(inviteUsers: InviteUsers) = apply { this.inviteUsers = inviteUsers } + fun inviteUsers(inviteUsers: InviteUsers?) = apply { body.inviteUsers(inviteUsers) } + + /** Alias for calling [Builder.inviteUsers] with `inviteUsers.orElse(null)`. */ + fun inviteUsers(inviteUsers: Optional) = inviteUsers(inviteUsers.getOrNull()) + + /** + * Sets [Builder.inviteUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.inviteUsers] with a well-typed [InviteUsers] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun inviteUsers(inviteUsers: JsonField) = apply { + body.inviteUsers(inviteUsers) + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, or in case you want to explicitly assert * the organization you are modifying, you may specify the id of the organization. */ - fun orgId(orgId: String) = apply { this.orgId = orgId } + fun orgId(orgId: String?) = apply { body.orgId(orgId) } + + /** Alias for calling [Builder.orgId] with `orgId.orElse(null)`. */ + fun orgId(orgId: Optional) = orgId(orgId.getOrNull()) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgId(orgId: JsonField) = apply { body.orgId(orgId) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, or in case you want to explicitly assert * the organization you are modifying, you may specify the name of the organization. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } /** Users to remove from the organization */ - fun removeUsers(removeUsers: RemoveUsers) = apply { this.removeUsers = removeUsers } + fun removeUsers(removeUsers: RemoveUsers?) = apply { body.removeUsers(removeUsers) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.removeUsers] with `removeUsers.orElse(null)`. */ + fun removeUsers(removeUsers: Optional) = removeUsers(removeUsers.getOrNull()) + + /** + * Sets [Builder.removeUsers] to an arbitrary JSON value. + * + * You should usually call [Builder.removeUsers] with a well-typed [RemoveUsers] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun removeUsers(removeUsers: JsonField) = apply { + body.removeUsers(removeUsers) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [OrganizationMemberUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): OrganizationMemberUpdateParams = OrganizationMemberUpdateParams( - inviteUsers, - orgId, - orgName, - removeUsers, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } /** Users to invite to the organization */ - @JsonDeserialize(builder = InviteUsers.Builder::class) @NoAutoDetect class InviteUsers + @JsonCreator private constructor( - private val ids: List?, - private val emails: List?, - private val sendInviteEmails: Boolean?, - private val groupIds: List?, - private val groupNames: List?, - private val groupId: String?, - private val groupName: String?, - private val additionalProperties: Map, + @JsonProperty("emails") + @ExcludeMissing + private val emails: JsonField> = JsonMissing.of(), + @JsonProperty("group_id") + @ExcludeMissing + private val groupId: JsonField = JsonMissing.of(), + @JsonProperty("group_ids") + @ExcludeMissing + private val groupIds: JsonField> = JsonMissing.of(), + @JsonProperty("group_name") + @ExcludeMissing + private val groupName: JsonField = JsonMissing.of(), + @JsonProperty("group_names") + @ExcludeMissing + private val groupNames: JsonField> = JsonMissing.of(), + @JsonProperty("ids") + @ExcludeMissing + private val ids: JsonField> = JsonMissing.of(), + @JsonProperty("send_invite_emails") + @ExcludeMissing + private val sendInviteEmails: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * Emails of users to invite + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun emails(): Optional> = Optional.ofNullable(emails.getNullable("emails")) - /** Ids of existing users to invite */ - @JsonProperty("ids") fun ids(): List? = ids + /** + * Singular form of group_ids + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupId(): Optional = Optional.ofNullable(groupId.getNullable("group_id")) - /** Emails of users to invite */ - @JsonProperty("emails") fun emails(): List? = emails + /** + * Optional list of group ids to add newly-invited users to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupIds(): Optional> = + Optional.ofNullable(groupIds.getNullable("group_ids")) - /** If true, send invite emails to the users who wore actually added */ - @JsonProperty("send_invite_emails") fun sendInviteEmails(): Boolean? = sendInviteEmails + /** + * Singular form of group_names + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupName(): Optional = Optional.ofNullable(groupName.getNullable("group_name")) - /** Optional list of group ids to add newly-invited users to. */ - @JsonProperty("group_ids") fun groupIds(): List? = groupIds + /** + * Optional list of group names to add newly-invited users to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun groupNames(): Optional> = + Optional.ofNullable(groupNames.getNullable("group_names")) - /** Optional list of group names to add newly-invited users to. */ - @JsonProperty("group_names") fun groupNames(): List? = groupNames + /** + * Ids of existing users to invite + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun ids(): Optional> = Optional.ofNullable(ids.getNullable("ids")) - /** Singular form of group_ids */ - @JsonProperty("group_id") fun groupId(): String? = groupId + /** + * If true, send invite emails to the users who wore actually added + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun sendInviteEmails(): Optional = + Optional.ofNullable(sendInviteEmails.getNullable("send_invite_emails")) - /** Singular form of group_names */ - @JsonProperty("group_name") fun groupName(): String? = groupName + /** + * Returns the raw JSON value of [emails]. + * + * Unlike [emails], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("emails") @ExcludeMissing fun _emails(): JsonField> = emails + + /** + * Returns the raw JSON value of [groupId]. + * + * Unlike [groupId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_id") @ExcludeMissing fun _groupId(): JsonField = groupId + + /** + * Returns the raw JSON value of [groupIds]. + * + * Unlike [groupIds], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_ids") + @ExcludeMissing + fun _groupIds(): JsonField> = groupIds + + /** + * Returns the raw JSON value of [groupName]. + * + * Unlike [groupName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_name") @ExcludeMissing fun _groupName(): JsonField = groupName + + /** + * Returns the raw JSON value of [groupNames]. + * + * Unlike [groupNames], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("group_names") + @ExcludeMissing + fun _groupNames(): JsonField> = groupNames + + /** + * Returns the raw JSON value of [ids]. + * + * Unlike [ids], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ids") @ExcludeMissing fun _ids(): JsonField> = ids + + /** + * Returns the raw JSON value of [sendInviteEmails]. + * + * Unlike [sendInviteEmails], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("send_invite_emails") + @ExcludeMissing + fun _sendInviteEmails(): JsonField = sendInviteEmails @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): InviteUsers = apply { + if (validated) { + return@apply } - return other is InviteUsers && - this.ids == other.ids && - this.emails == other.emails && - this.sendInviteEmails == other.sendInviteEmails && - this.groupIds == other.groupIds && - this.groupNames == other.groupNames && - this.groupId == other.groupId && - this.groupName == other.groupName && - this.additionalProperties == other.additionalProperties + emails() + groupId() + groupIds() + groupName() + groupNames() + ids() + sendInviteEmails() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - ids, - emails, - sendInviteEmails, - groupIds, - groupNames, - groupId, - groupName, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "InviteUsers{ids=$ids, emails=$emails, sendInviteEmails=$sendInviteEmails, groupIds=$groupIds, groupNames=$groupNames, groupId=$groupId, groupName=$groupName, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [InviteUsers]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [InviteUsers]. */ + class Builder internal constructor() { - private var ids: List? = null - private var emails: List? = null - private var sendInviteEmails: Boolean? = null - private var groupIds: List? = null - private var groupNames: List? = null - private var groupId: String? = null - private var groupName: String? = null + private var emails: JsonField>? = null + private var groupId: JsonField = JsonMissing.of() + private var groupIds: JsonField>? = null + private var groupName: JsonField = JsonMissing.of() + private var groupNames: JsonField>? = null + private var ids: JsonField>? = null + private var sendInviteEmails: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(inviteUsers: InviteUsers) = apply { - this.ids = inviteUsers.ids - this.emails = inviteUsers.emails - this.sendInviteEmails = inviteUsers.sendInviteEmails - this.groupIds = inviteUsers.groupIds - this.groupNames = inviteUsers.groupNames - this.groupId = inviteUsers.groupId - this.groupName = inviteUsers.groupName - additionalProperties(inviteUsers.additionalProperties) + emails = inviteUsers.emails.map { it.toMutableList() } + groupId = inviteUsers.groupId + groupIds = inviteUsers.groupIds.map { it.toMutableList() } + groupName = inviteUsers.groupName + groupNames = inviteUsers.groupNames.map { it.toMutableList() } + ids = inviteUsers.ids.map { it.toMutableList() } + sendInviteEmails = inviteUsers.sendInviteEmails + additionalProperties = inviteUsers.additionalProperties.toMutableMap() } - /** Ids of existing users to invite */ - @JsonProperty("ids") fun ids(ids: List) = apply { this.ids = ids } - /** Emails of users to invite */ - @JsonProperty("emails") - fun emails(emails: List) = apply { this.emails = emails } + fun emails(emails: List?) = emails(JsonField.ofNullable(emails)) - /** If true, send invite emails to the users who wore actually added */ - @JsonProperty("send_invite_emails") - fun sendInviteEmails(sendInviteEmails: Boolean) = apply { - this.sendInviteEmails = sendInviteEmails + /** Alias for calling [Builder.emails] with `emails.orElse(null)`. */ + fun emails(emails: Optional>) = emails(emails.getOrNull()) + + /** + * Sets [Builder.emails] to an arbitrary JSON value. + * + * You should usually call [Builder.emails] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun emails(emails: JsonField>) = apply { + this.emails = emails.map { it.toMutableList() } } + /** + * Adds a single [String] to [emails]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEmail(email: String) = apply { + emails = + (emails ?: JsonField.of(mutableListOf())).also { + checkKnown("emails", it).add(email) + } + } + + /** Singular form of group_ids */ + fun groupId(groupId: String?) = groupId(JsonField.ofNullable(groupId)) + + /** Alias for calling [Builder.groupId] with `groupId.orElse(null)`. */ + fun groupId(groupId: Optional) = groupId(groupId.getOrNull()) + + /** + * Sets [Builder.groupId] to an arbitrary JSON value. + * + * You should usually call [Builder.groupId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupId(groupId: JsonField) = apply { this.groupId = groupId } + /** Optional list of group ids to add newly-invited users to. */ - @JsonProperty("group_ids") - fun groupIds(groupIds: List) = apply { this.groupIds = groupIds } + fun groupIds(groupIds: List?) = groupIds(JsonField.ofNullable(groupIds)) - /** Optional list of group names to add newly-invited users to. */ - @JsonProperty("group_names") - fun groupNames(groupNames: List) = apply { this.groupNames = groupNames } + /** Alias for calling [Builder.groupIds] with `groupIds.orElse(null)`. */ + fun groupIds(groupIds: Optional>) = groupIds(groupIds.getOrNull()) - /** Singular form of group_ids */ - @JsonProperty("group_id") - fun groupId(groupId: String) = apply { this.groupId = groupId } + /** + * Sets [Builder.groupIds] to an arbitrary JSON value. + * + * You should usually call [Builder.groupIds] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupIds(groupIds: JsonField>) = apply { + this.groupIds = groupIds.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [groupIds]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addGroupId(groupId: String) = apply { + groupIds = + (groupIds ?: JsonField.of(mutableListOf())).also { + checkKnown("groupIds", it).add(groupId) + } + } /** Singular form of group_names */ - @JsonProperty("group_name") - fun groupName(groupName: String) = apply { this.groupName = groupName } + fun groupName(groupName: String?) = groupName(JsonField.ofNullable(groupName)) + + /** Alias for calling [Builder.groupName] with `groupName.orElse(null)`. */ + fun groupName(groupName: Optional) = groupName(groupName.getOrNull()) + + /** + * Sets [Builder.groupName] to an arbitrary JSON value. + * + * You should usually call [Builder.groupName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupName(groupName: JsonField) = apply { this.groupName = groupName } + + /** Optional list of group names to add newly-invited users to. */ + fun groupNames(groupNames: List?) = groupNames(JsonField.ofNullable(groupNames)) + + /** Alias for calling [Builder.groupNames] with `groupNames.orElse(null)`. */ + fun groupNames(groupNames: Optional>) = groupNames(groupNames.getOrNull()) + + /** + * Sets [Builder.groupNames] to an arbitrary JSON value. + * + * You should usually call [Builder.groupNames] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun groupNames(groupNames: JsonField>) = apply { + this.groupNames = groupNames.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [groupNames]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addGroupName(groupName: String) = apply { + groupNames = + (groupNames ?: JsonField.of(mutableListOf())).also { + checkKnown("groupNames", it).add(groupName) + } + } + + /** Ids of existing users to invite */ + fun ids(ids: List?) = ids(JsonField.ofNullable(ids)) + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional>) = ids(ids.getOrNull()) + + /** + * Sets [Builder.ids] to an arbitrary JSON value. + * + * You should usually call [Builder.ids] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ids(ids: JsonField>) = apply { + this.ids = ids.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [ids]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addId(id: String) = apply { + ids = (ids ?: JsonField.of(mutableListOf())).also { checkKnown("ids", it).add(id) } + } + + /** If true, send invite emails to the users who wore actually added */ + fun sendInviteEmails(sendInviteEmails: Boolean?) = + sendInviteEmails(JsonField.ofNullable(sendInviteEmails)) + + /** + * Alias for [Builder.sendInviteEmails]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun sendInviteEmails(sendInviteEmails: Boolean) = + sendInviteEmails(sendInviteEmails as Boolean?) + + /** + * Alias for calling [Builder.sendInviteEmails] with `sendInviteEmails.orElse(null)`. + */ + fun sendInviteEmails(sendInviteEmails: Optional) = + sendInviteEmails(sendInviteEmails.getOrNull()) + + /** + * Sets [Builder.sendInviteEmails] to an arbitrary JSON value. + * + * You should usually call [Builder.sendInviteEmails] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun sendInviteEmails(sendInviteEmails: JsonField) = apply { + this.sendInviteEmails = sendInviteEmails + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [InviteUsers]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): InviteUsers = InviteUsers( - ids?.toUnmodifiable(), - emails?.toUnmodifiable(), - sendInviteEmails, - groupIds?.toUnmodifiable(), - groupNames?.toUnmodifiable(), + (emails ?: JsonMissing.of()).map { it.toImmutable() }, groupId, + (groupIds ?: JsonMissing.of()).map { it.toImmutable() }, groupName, - additionalProperties.toUnmodifiable(), + (groupNames ?: JsonMissing.of()).map { it.toImmutable() }, + (ids ?: JsonMissing.of()).map { it.toImmutable() }, + sendInviteEmails, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InviteUsers && emails == other.emails && groupId == other.groupId && groupIds == other.groupIds && groupName == other.groupName && groupNames == other.groupNames && ids == other.ids && sendInviteEmails == other.sendInviteEmails && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(emails, groupId, groupIds, groupName, groupNames, ids, sendInviteEmails, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InviteUsers{emails=$emails, groupId=$groupId, groupIds=$groupIds, groupName=$groupName, groupNames=$groupNames, ids=$ids, sendInviteEmails=$sendInviteEmails, additionalProperties=$additionalProperties}" } /** Users to remove from the organization */ - @JsonDeserialize(builder = RemoveUsers.Builder::class) @NoAutoDetect class RemoveUsers + @JsonCreator private constructor( - private val ids: List?, - private val emails: List?, - private val additionalProperties: Map, + @JsonProperty("emails") + @ExcludeMissing + private val emails: JsonField> = JsonMissing.of(), + @JsonProperty("ids") + @ExcludeMissing + private val ids: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * Emails of users to remove + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun emails(): Optional> = Optional.ofNullable(emails.getNullable("emails")) - /** Ids of users to remove */ - @JsonProperty("ids") fun ids(): List? = ids + /** + * Ids of users to remove + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun ids(): Optional> = Optional.ofNullable(ids.getNullable("ids")) - /** Emails of users to remove */ - @JsonProperty("emails") fun emails(): List? = emails + /** + * Returns the raw JSON value of [emails]. + * + * Unlike [emails], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("emails") @ExcludeMissing fun _emails(): JsonField> = emails + + /** + * Returns the raw JSON value of [ids]. + * + * Unlike [ids], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ids") @ExcludeMissing fun _ids(): JsonField> = ids @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RemoveUsers = apply { + if (validated) { + return@apply } - return other is RemoveUsers && - this.ids == other.ids && - this.emails == other.emails && - this.additionalProperties == other.additionalProperties + emails() + ids() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - ids, - emails, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "RemoveUsers{ids=$ids, emails=$emails, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [RemoveUsers]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RemoveUsers]. */ + class Builder internal constructor() { - private var ids: List? = null - private var emails: List? = null + private var emails: JsonField>? = null + private var ids: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(removeUsers: RemoveUsers) = apply { - this.ids = removeUsers.ids - this.emails = removeUsers.emails - additionalProperties(removeUsers.additionalProperties) + emails = removeUsers.emails.map { it.toMutableList() } + ids = removeUsers.ids.map { it.toMutableList() } + additionalProperties = removeUsers.additionalProperties.toMutableMap() + } + + /** Emails of users to remove */ + fun emails(emails: List?) = emails(JsonField.ofNullable(emails)) + + /** Alias for calling [Builder.emails] with `emails.orElse(null)`. */ + fun emails(emails: Optional>) = emails(emails.getOrNull()) + + /** + * Sets [Builder.emails] to an arbitrary JSON value. + * + * You should usually call [Builder.emails] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun emails(emails: JsonField>) = apply { + this.emails = emails.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [emails]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEmail(email: String) = apply { + emails = + (emails ?: JsonField.of(mutableListOf())).also { + checkKnown("emails", it).add(email) + } } /** Ids of users to remove */ - @JsonProperty("ids") fun ids(ids: List) = apply { this.ids = ids } + fun ids(ids: List?) = ids(JsonField.ofNullable(ids)) - /** Emails of users to remove */ - @JsonProperty("emails") - fun emails(emails: List) = apply { this.emails = emails } + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional>) = ids(ids.getOrNull()) + + /** + * Sets [Builder.ids] to an arbitrary JSON value. + * + * You should usually call [Builder.ids] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ids(ids: JsonField>) = apply { + this.ids = ids.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [ids]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addId(id: String) = apply { + ids = (ids ?: JsonField.of(mutableListOf())).also { checkKnown("ids", it).add(id) } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RemoveUsers]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): RemoveUsers = RemoveUsers( - ids?.toUnmodifiable(), - emails?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (emails ?: JsonMissing.of()).map { it.toImmutable() }, + (ids ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RemoveUsers && emails == other.emails && ids == other.ids && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(emails, ids, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RemoveUsers{emails=$emails, ids=$ids, additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OrganizationMemberUpdateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "OrganizationMemberUpdateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParams.kt index 6999669c..86b3cebc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get an organization object by its id */ class OrganizationRetrieveParams -constructor( +private constructor( private val organizationId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Organization id */ fun organizationId(): String = organizationId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is OrganizationRetrieveParams && - this.organizationId == other.organizationId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - organizationId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "OrganizationRetrieveParams{organizationId=$organizationId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [OrganizationRetrieveParams]. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [OrganizationRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var organizationId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(organizationRetrieveParams: OrganizationRetrieveParams) = apply { - this.organizationId = organizationRetrieveParams.organizationId - additionalQueryParams(organizationRetrieveParams.additionalQueryParams) - additionalHeaders(organizationRetrieveParams.additionalHeaders) + organizationId = organizationRetrieveParams.organizationId + additionalHeaders = organizationRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = organizationRetrieveParams.additionalQueryParams.toBuilder() } /** Organization id */ fun organizationId(organizationId: String) = apply { this.organizationId = organizationId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [OrganizationRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): OrganizationRetrieveParams = OrganizationRetrieveParams( - checkNotNull(organizationId) { "`organizationId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("organizationId", organizationId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OrganizationRetrieveParams && organizationId == other.organizationId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(organizationId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "OrganizationRetrieveParams{organizationId=$organizationId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationUpdateParams.kt index a513fc50..36741dd2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/OrganizationUpdateParams.kt @@ -3,57 +3,119 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update an organization object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ class OrganizationUpdateParams -constructor( +private constructor( private val organizationId: String, - private val apiUrl: String?, - private val isUniversalApi: Boolean?, - private val name: String?, - private val proxyUrl: String?, - private val realtimeUrl: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Organization id */ fun organizationId(): String = organizationId - fun apiUrl(): Optional = Optional.ofNullable(apiUrl) - - fun isUniversalApi(): Optional = Optional.ofNullable(isUniversalApi) - - fun name(): Optional = Optional.ofNullable(name) - - fun proxyUrl(): Optional = Optional.ofNullable(proxyUrl) - - fun realtimeUrl(): Optional = Optional.ofNullable(realtimeUrl) - - @JvmSynthetic - internal fun getBody(): OrganizationUpdateBody { - return OrganizationUpdateBody( - apiUrl, - isUniversalApi, - name, - proxyUrl, - realtimeUrl, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun apiUrl(): Optional = body.apiUrl() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun isUniversalApi(): Optional = body.isUniversalApi() + + /** + * Name of the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun proxyUrl(): Optional = body.proxyUrl() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun realtimeUrl(): Optional = body.realtimeUrl() + + /** + * Returns the raw JSON value of [apiUrl]. + * + * Unlike [apiUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _apiUrl(): JsonField = body._apiUrl() + + /** + * Returns the raw JSON value of [isUniversalApi]. + * + * Unlike [isUniversalApi], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _isUniversalApi(): JsonField = body._isUniversalApi() + + /** + * 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 [proxyUrl]. + * + * Unlike [proxyUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _proxyUrl(): JsonField = body._proxyUrl() + + /** + * Returns the raw JSON value of [realtimeUrl]. + * + * Unlike [realtimeUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _realtimeUrl(): JsonField = body._realtimeUrl() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -62,287 +124,548 @@ constructor( } } - @JsonDeserialize(builder = OrganizationUpdateBody.Builder::class) @NoAutoDetect - class OrganizationUpdateBody - internal constructor( - private val apiUrl: String?, - private val isUniversalApi: Boolean?, - private val name: String?, - private val proxyUrl: String?, - private val realtimeUrl: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("api_url") + @ExcludeMissing + private val apiUrl: JsonField = JsonMissing.of(), + @JsonProperty("is_universal_api") + @ExcludeMissing + private val isUniversalApi: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("proxy_url") + @ExcludeMissing + private val proxyUrl: JsonField = JsonMissing.of(), + @JsonProperty("realtime_url") + @ExcludeMissing + private val realtimeUrl: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - @JsonProperty("api_url") fun apiUrl(): String? = apiUrl - - @JsonProperty("is_universal_api") fun isUniversalApi(): Boolean? = isUniversalApi - - /** Name of the organization */ - @JsonProperty("name") fun name(): String? = name - - @JsonProperty("proxy_url") fun proxyUrl(): String? = proxyUrl - - @JsonProperty("realtime_url") fun realtimeUrl(): String? = realtimeUrl + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun apiUrl(): Optional = Optional.ofNullable(apiUrl.getNullable("api_url")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun isUniversalApi(): Optional = + Optional.ofNullable(isUniversalApi.getNullable("is_universal_api")) + + /** + * Name of the organization + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun proxyUrl(): Optional = Optional.ofNullable(proxyUrl.getNullable("proxy_url")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun realtimeUrl(): Optional = + Optional.ofNullable(realtimeUrl.getNullable("realtime_url")) + + /** + * Returns the raw JSON value of [apiUrl]. + * + * Unlike [apiUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("api_url") @ExcludeMissing fun _apiUrl(): JsonField = apiUrl + + /** + * Returns the raw JSON value of [isUniversalApi]. + * + * Unlike [isUniversalApi], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("is_universal_api") + @ExcludeMissing + fun _isUniversalApi(): JsonField = isUniversalApi + + /** + * 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 [proxyUrl]. + * + * Unlike [proxyUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("proxy_url") @ExcludeMissing fun _proxyUrl(): JsonField = proxyUrl + + /** + * Returns the raw JSON value of [realtimeUrl]. + * + * Unlike [realtimeUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("realtime_url") + @ExcludeMissing + fun _realtimeUrl(): JsonField = realtimeUrl @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is OrganizationUpdateBody && - this.apiUrl == other.apiUrl && - this.isUniversalApi == other.isUniversalApi && - this.name == other.name && - this.proxyUrl == other.proxyUrl && - this.realtimeUrl == other.realtimeUrl && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - apiUrl, - isUniversalApi, - name, - proxyUrl, - realtimeUrl, - additionalProperties, - ) - } - return hashCode + apiUrl() + isUniversalApi() + name() + proxyUrl() + realtimeUrl() + validated = true } - override fun toString() = - "OrganizationUpdateBody{apiUrl=$apiUrl, isUniversalApi=$isUniversalApi, name=$name, proxyUrl=$proxyUrl, realtimeUrl=$realtimeUrl, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var apiUrl: String? = null - private var isUniversalApi: Boolean? = null - private var name: String? = null - private var proxyUrl: String? = null - private var realtimeUrl: String? = null + private var apiUrl: JsonField = JsonMissing.of() + private var isUniversalApi: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var proxyUrl: JsonField = JsonMissing.of() + private var realtimeUrl: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(organizationUpdateBody: OrganizationUpdateBody) = apply { - this.apiUrl = organizationUpdateBody.apiUrl - this.isUniversalApi = organizationUpdateBody.isUniversalApi - this.name = organizationUpdateBody.name - this.proxyUrl = organizationUpdateBody.proxyUrl - this.realtimeUrl = organizationUpdateBody.realtimeUrl - additionalProperties(organizationUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + apiUrl = body.apiUrl + isUniversalApi = body.isUniversalApi + name = body.name + proxyUrl = body.proxyUrl + realtimeUrl = body.realtimeUrl + additionalProperties = body.additionalProperties.toMutableMap() } - @JsonProperty("api_url") fun apiUrl(apiUrl: String) = apply { this.apiUrl = apiUrl } - - @JsonProperty("is_universal_api") - fun isUniversalApi(isUniversalApi: Boolean) = apply { + fun apiUrl(apiUrl: String?) = apiUrl(JsonField.ofNullable(apiUrl)) + + /** Alias for calling [Builder.apiUrl] with `apiUrl.orElse(null)`. */ + fun apiUrl(apiUrl: Optional) = apiUrl(apiUrl.getOrNull()) + + /** + * Sets [Builder.apiUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.apiUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun apiUrl(apiUrl: JsonField) = apply { this.apiUrl = apiUrl } + + fun isUniversalApi(isUniversalApi: Boolean?) = + isUniversalApi(JsonField.ofNullable(isUniversalApi)) + + /** + * Alias for [Builder.isUniversalApi]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isUniversalApi(isUniversalApi: Boolean) = isUniversalApi(isUniversalApi as Boolean?) + + /** Alias for calling [Builder.isUniversalApi] with `isUniversalApi.orElse(null)`. */ + fun isUniversalApi(isUniversalApi: Optional) = + isUniversalApi(isUniversalApi.getOrNull()) + + /** + * Sets [Builder.isUniversalApi] to an arbitrary JSON value. + * + * You should usually call [Builder.isUniversalApi] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isUniversalApi(isUniversalApi: JsonField) = apply { this.isUniversalApi = isUniversalApi } /** Name of the organization */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } - - @JsonProperty("proxy_url") - fun proxyUrl(proxyUrl: String) = apply { this.proxyUrl = proxyUrl } - - @JsonProperty("realtime_url") - fun realtimeUrl(realtimeUrl: String) = apply { this.realtimeUrl = realtimeUrl } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } + + fun proxyUrl(proxyUrl: String?) = proxyUrl(JsonField.ofNullable(proxyUrl)) + + /** Alias for calling [Builder.proxyUrl] with `proxyUrl.orElse(null)`. */ + fun proxyUrl(proxyUrl: Optional) = proxyUrl(proxyUrl.getOrNull()) + + /** + * Sets [Builder.proxyUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.proxyUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun proxyUrl(proxyUrl: JsonField) = apply { this.proxyUrl = proxyUrl } + + fun realtimeUrl(realtimeUrl: String?) = realtimeUrl(JsonField.ofNullable(realtimeUrl)) + + /** Alias for calling [Builder.realtimeUrl] with `realtimeUrl.orElse(null)`. */ + fun realtimeUrl(realtimeUrl: Optional) = realtimeUrl(realtimeUrl.getOrNull()) + + /** + * Sets [Builder.realtimeUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.realtimeUrl] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun realtimeUrl(realtimeUrl: JsonField) = apply { + this.realtimeUrl = realtimeUrl + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): OrganizationUpdateBody = - OrganizationUpdateBody( + 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. + */ + fun build(): Body = + Body( apiUrl, isUniversalApi, name, proxyUrl, realtimeUrl, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && apiUrl == other.apiUrl && isUniversalApi == other.isUniversalApi && name == other.name && proxyUrl == other.proxyUrl && realtimeUrl == other.realtimeUrl && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is OrganizationUpdateParams && - this.organizationId == other.organizationId && - this.apiUrl == other.apiUrl && - this.isUniversalApi == other.isUniversalApi && - this.name == other.name && - this.proxyUrl == other.proxyUrl && - this.realtimeUrl == other.realtimeUrl && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(apiUrl, isUniversalApi, name, proxyUrl, realtimeUrl, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - organizationId, - apiUrl, - isUniversalApi, - name, - proxyUrl, - realtimeUrl, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "OrganizationUpdateParams{organizationId=$organizationId, apiUrl=$apiUrl, isUniversalApi=$isUniversalApi, name=$name, proxyUrl=$proxyUrl, realtimeUrl=$realtimeUrl, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{apiUrl=$apiUrl, isUniversalApi=$isUniversalApi, name=$name, proxyUrl=$proxyUrl, realtimeUrl=$realtimeUrl, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [OrganizationUpdateParams]. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [OrganizationUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var organizationId: String? = null - private var apiUrl: String? = null - private var isUniversalApi: Boolean? = null - private var name: String? = null - private var proxyUrl: String? = null - private var realtimeUrl: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(organizationUpdateParams: OrganizationUpdateParams) = apply { - this.organizationId = organizationUpdateParams.organizationId - this.apiUrl = organizationUpdateParams.apiUrl - this.isUniversalApi = organizationUpdateParams.isUniversalApi - this.name = organizationUpdateParams.name - this.proxyUrl = organizationUpdateParams.proxyUrl - this.realtimeUrl = organizationUpdateParams.realtimeUrl - additionalQueryParams(organizationUpdateParams.additionalQueryParams) - additionalHeaders(organizationUpdateParams.additionalHeaders) - additionalBodyProperties(organizationUpdateParams.additionalBodyProperties) + organizationId = organizationUpdateParams.organizationId + body = organizationUpdateParams.body.toBuilder() + additionalHeaders = organizationUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = organizationUpdateParams.additionalQueryParams.toBuilder() } /** Organization id */ fun organizationId(organizationId: String) = apply { this.organizationId = organizationId } - fun apiUrl(apiUrl: String) = apply { this.apiUrl = apiUrl } - - fun isUniversalApi(isUniversalApi: Boolean) = apply { this.isUniversalApi = isUniversalApi } + fun apiUrl(apiUrl: String?) = apply { body.apiUrl(apiUrl) } + + /** Alias for calling [Builder.apiUrl] with `apiUrl.orElse(null)`. */ + fun apiUrl(apiUrl: Optional) = apiUrl(apiUrl.getOrNull()) + + /** + * Sets [Builder.apiUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.apiUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun apiUrl(apiUrl: JsonField) = apply { body.apiUrl(apiUrl) } + + fun isUniversalApi(isUniversalApi: Boolean?) = apply { body.isUniversalApi(isUniversalApi) } + + /** + * Alias for [Builder.isUniversalApi]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun isUniversalApi(isUniversalApi: Boolean) = isUniversalApi(isUniversalApi as Boolean?) + + /** Alias for calling [Builder.isUniversalApi] with `isUniversalApi.orElse(null)`. */ + fun isUniversalApi(isUniversalApi: Optional) = + isUniversalApi(isUniversalApi.getOrNull()) + + /** + * Sets [Builder.isUniversalApi] to an arbitrary JSON value. + * + * You should usually call [Builder.isUniversalApi] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun isUniversalApi(isUniversalApi: JsonField) = apply { + body.isUniversalApi(isUniversalApi) + } /** Name of the organization */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } + + fun proxyUrl(proxyUrl: String?) = apply { body.proxyUrl(proxyUrl) } + + /** Alias for calling [Builder.proxyUrl] with `proxyUrl.orElse(null)`. */ + fun proxyUrl(proxyUrl: Optional) = proxyUrl(proxyUrl.getOrNull()) + + /** + * Sets [Builder.proxyUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.proxyUrl] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun proxyUrl(proxyUrl: JsonField) = apply { body.proxyUrl(proxyUrl) } + + fun realtimeUrl(realtimeUrl: String?) = apply { body.realtimeUrl(realtimeUrl) } + + /** Alias for calling [Builder.realtimeUrl] with `realtimeUrl.orElse(null)`. */ + fun realtimeUrl(realtimeUrl: Optional) = realtimeUrl(realtimeUrl.getOrNull()) + + /** + * Sets [Builder.realtimeUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.realtimeUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun realtimeUrl(realtimeUrl: JsonField) = apply { body.realtimeUrl(realtimeUrl) } - fun proxyUrl(proxyUrl: String) = apply { this.proxyUrl = proxyUrl } + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } - fun realtimeUrl(realtimeUrl: String) = apply { this.realtimeUrl = realtimeUrl } + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + 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 putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [OrganizationUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .organizationId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): OrganizationUpdateParams = OrganizationUpdateParams( - checkNotNull(organizationId) { "`organizationId` is required but was not set" }, - apiUrl, - isUniversalApi, - name, - proxyUrl, - realtimeUrl, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("organizationId", organizationId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OrganizationUpdateParams && organizationId == other.organizationId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(organizationId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "OrganizationUpdateParams{organizationId=$organizationId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutput.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutput.kt index 3c0f52bc..7a4c2743 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutput.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutput.kt @@ -8,196 +8,322 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = PatchOrganizationMembersOutput.Builder::class) @NoAutoDetect class PatchOrganizationMembersOutput +@JsonCreator private constructor( - private val status: JsonField, - private val sendEmailError: JsonField, - private val additionalProperties: Map, + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("status") + @ExcludeMissing + private val status: JsonField = JsonMissing.of(), + @JsonProperty("send_email_error") + @ExcludeMissing + private val sendEmailError: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * The id of the org that was modified. + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") + /** + * @throws BraintrustInvalidDataException 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 status(): Status = status.getRequired("status") /** * If invite emails failed to send for some reason, the patch operation will still complete, but * we will return an error message here + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun sendEmailError(): Optional = Optional.ofNullable(sendEmailError.getNullable("send_email_error")) - @JsonProperty("status") @ExcludeMissing fun _status() = status + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId /** - * If invite emails failed to send for some reason, the patch operation will still complete, but - * we will return an error message here + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("send_email_error") @ExcludeMissing fun _sendEmailError() = sendEmailError + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [sendEmailError]. + * + * Unlike [sendEmailError], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("send_email_error") + @ExcludeMissing + fun _sendEmailError(): JsonField = sendEmailError @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): PatchOrganizationMembersOutput = apply { - if (!validated) { - status() - sendEmailError() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): PatchOrganizationMembersOutput = apply { + if (validated) { + return@apply } - return other is PatchOrganizationMembersOutput && - this.status == other.status && - this.sendEmailError == other.sendEmailError && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - status, - sendEmailError, - additionalProperties, - ) - } - return hashCode + orgId() + status() + sendEmailError() + validated = true } - override fun toString() = - "PatchOrganizationMembersOutput{status=$status, sendEmailError=$sendEmailError, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [PatchOrganizationMembersOutput]. + * + * The following fields are required: + * ```java + * .orgId() + * .status() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [PatchOrganizationMembersOutput]. */ + class Builder internal constructor() { - private var status: JsonField = JsonMissing.of() + private var orgId: JsonField? = null + private var status: JsonField? = null private var sendEmailError: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(patchOrganizationMembersOutput: PatchOrganizationMembersOutput) = apply { - this.status = patchOrganizationMembersOutput.status - this.sendEmailError = patchOrganizationMembersOutput.sendEmailError - additionalProperties(patchOrganizationMembersOutput.additionalProperties) + orgId = patchOrganizationMembersOutput.orgId + status = patchOrganizationMembersOutput.status + sendEmailError = patchOrganizationMembersOutput.sendEmailError + additionalProperties = + patchOrganizationMembersOutput.additionalProperties.toMutableMap() } + /** The id of the org that was modified. */ + fun orgId(orgId: String) = orgId(JsonField.of(orgId)) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgId(orgId: JsonField) = apply { this.orgId = orgId } + fun status(status: Status) = status(JsonField.of(status)) - @JsonProperty("status") - @ExcludeMissing + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun status(status: JsonField) = apply { this.status = status } /** * If invite emails failed to send for some reason, the patch operation will still complete, * but we will return an error message here */ - fun sendEmailError(sendEmailError: String) = sendEmailError(JsonField.of(sendEmailError)) + fun sendEmailError(sendEmailError: String?) = + sendEmailError(JsonField.ofNullable(sendEmailError)) + + /** Alias for calling [Builder.sendEmailError] with `sendEmailError.orElse(null)`. */ + fun sendEmailError(sendEmailError: Optional) = + sendEmailError(sendEmailError.getOrNull()) /** - * If invite emails failed to send for some reason, the patch operation will still complete, - * but we will return an error message here + * Sets [Builder.sendEmailError] to an arbitrary JSON value. + * + * You should usually call [Builder.sendEmailError] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("send_email_error") - @ExcludeMissing fun sendEmailError(sendEmailError: JsonField) = apply { this.sendEmailError = sendEmailError } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [PatchOrganizationMembersOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .orgId() + * .status() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): PatchOrganizationMembersOutput = PatchOrganizationMembersOutput( - status, + checkRequired("orgId", orgId), + checkRequired("status", status), sendEmailError, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Status - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + class Status @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Status && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val SUCCESS = Status(JsonField.of("success")) + @JvmField val SUCCESS = of("success") @JvmStatic fun of(value: String) = Status(JsonField.of(value)) } + /** An enum containing [Status]'s known values. */ enum class Known { - SUCCESS, + SUCCESS } + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] 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 { SUCCESS, + /** An enum member indicating that [Status] 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) { SUCCESS -> Value.SUCCESS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { SUCCESS -> Known.SUCCESS else -> throw BraintrustInvalidDataException("Unknown Status: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Status && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PatchOrganizationMembersOutput && orgId == other.orgId && status == other.status && sendEmailError == other.sendEmailError && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(orgId, status, sendEmailError, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PatchOrganizationMembersOutput{orgId=$orgId, status=$status, sendEmailError=$sendEmailError, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PathLookupFilter.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PathLookupFilter.kt deleted file mode 100755 index d1127b0d..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PathLookupFilter.kt +++ /dev/null @@ -1,245 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.util.Objects - -/** - * A path-lookup filter describes an equality comparison against a specific sub-field in the event - * row. For instance, if you wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": - * "hello"}}}}`, pass `path=["input", "a", "b", "c"]` and `value="hello"` - */ -@JsonDeserialize(builder = PathLookupFilter.Builder::class) -@NoAutoDetect -class PathLookupFilter -private constructor( - private val type: JsonField, - private val path: JsonField>, - private val value: JsonValue, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Denotes the type of filter as a path-lookup filter */ - fun type(): Type = type.getRequired("type") - - /** - * List of fields describing the path to the value to be checked against. For instance, if you - * wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass - * `path=["input", "a", "b", "c"]` - */ - fun path(): List = path.getRequired("path") - - /** - * The value to compare equality-wise against the event value at the specified `path`. The value - * must be a "primitive", that is, any JSON-serializable object except for objects and arrays. - * For instance, if you wish to filter on the value of "input.a.b.c" in the object `{"input": - * {"a": {"b": {"c": "hello"}}}}`, pass `value="hello"` - */ - fun value(): JsonValue = value - - /** Denotes the type of filter as a path-lookup filter */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - /** - * List of fields describing the path to the value to be checked against. For instance, if you - * wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass - * `path=["input", "a", "b", "c"]` - */ - @JsonProperty("path") @ExcludeMissing fun _path() = path - - /** - * The value to compare equality-wise against the event value at the specified `path`. The value - * must be a "primitive", that is, any JSON-serializable object except for objects and arrays. - * For instance, if you wish to filter on the value of "input.a.b.c" in the object `{"input": - * {"a": {"b": {"c": "hello"}}}}`, pass `value="hello"` - */ - @JsonProperty("value") @ExcludeMissing fun _value() = value - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): PathLookupFilter = apply { - if (!validated) { - type() - path() - value() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PathLookupFilter && - this.type == other.type && - this.path == other.path && - this.value == other.value && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - path, - value, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "PathLookupFilter{type=$type, path=$path, value=$value, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var type: JsonField = JsonMissing.of() - private var path: JsonField> = JsonMissing.of() - private var value: JsonValue = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(pathLookupFilter: PathLookupFilter) = apply { - this.type = pathLookupFilter.type - this.path = pathLookupFilter.path - this.value = pathLookupFilter.value - additionalProperties(pathLookupFilter.additionalProperties) - } - - /** Denotes the type of filter as a path-lookup filter */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Denotes the type of filter as a path-lookup filter */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - /** - * List of fields describing the path to the value to be checked against. For instance, if - * you wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass - * `path=["input", "a", "b", "c"]` - */ - fun path(path: List) = path(JsonField.of(path)) - - /** - * List of fields describing the path to the value to be checked against. For instance, if - * you wish to filter on the value of `c` in `{"input": {"a": {"b": {"c": "hello"}}}}`, pass - * `path=["input", "a", "b", "c"]` - */ - @JsonProperty("path") - @ExcludeMissing - fun path(path: JsonField>) = apply { this.path = path } - - /** - * The value to compare equality-wise against the event value at the specified `path`. The - * value must be a "primitive", that is, any JSON-serializable object except for objects and - * arrays. For instance, if you wish to filter on the value of "input.a.b.c" in the object - * `{"input": {"a": {"b": {"c": "hello"}}}}`, pass `value="hello"` - */ - @JsonProperty("value") - @ExcludeMissing - fun value(value: JsonValue) = apply { this.value = value } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): PathLookupFilter = - PathLookupFilter( - type, - path.map { it.toUnmodifiable() }, - value, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val PATH_LOOKUP = Type(JsonField.of("path_lookup")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - PATH_LOOKUP, - } - - enum class Value { - PATH_LOOKUP, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - PATH_LOOKUP -> Value.PATH_LOOKUP - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - PATH_LOOKUP -> Known.PATH_LOOKUP - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Permission.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Permission.kt new file mode 100644 index 00000000..7b884f8d --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Permission.kt @@ -0,0 +1,146 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +/** + * Each permission permits a certain type of operation on an object in the system + * + * Permissions can be assigned to to objects on an individual basis, or grouped into roles + */ +class Permission @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 CREATE = of("create") + + @JvmField val READ = of("read") + + @JvmField val UPDATE = of("update") + + @JvmField val DELETE = of("delete") + + @JvmField val CREATE_ACLS = of("create_acls") + + @JvmField val READ_ACLS = of("read_acls") + + @JvmField val UPDATE_ACLS = of("update_acls") + + @JvmField val DELETE_ACLS = of("delete_acls") + + @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) + } + + /** An enum containing [Permission]'s known values. */ + enum class Known { + CREATE, + READ, + UPDATE, + DELETE, + CREATE_ACLS, + READ_ACLS, + UPDATE_ACLS, + DELETE_ACLS, + } + + /** + * An enum containing [Permission]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Permission] 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 { + CREATE, + READ, + UPDATE, + DELETE, + CREATE_ACLS, + READ_ACLS, + UPDATE_ACLS, + DELETE_ACLS, + /** An enum member indicating that [Permission] 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) { + CREATE -> Value.CREATE + READ -> Value.READ + UPDATE -> Value.UPDATE + DELETE -> Value.DELETE + CREATE_ACLS -> Value.CREATE_ACLS + READ_ACLS -> Value.READ_ACLS + UPDATE_ACLS -> Value.UPDATE_ACLS + DELETE_ACLS -> Value.DELETE_ACLS + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CREATE -> Known.CREATE + READ -> Known.READ + UPDATE -> Known.UPDATE + DELETE -> Known.DELETE + CREATE_ACLS -> Known.CREATE_ACLS + READ_ACLS -> Known.READ_ACLS + UPDATE_ACLS -> Known.UPDATE_ACLS + DELETE_ACLS -> Known.DELETE_ACLS + else -> throw BraintrustInvalidDataException("Unknown Permission: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Permission && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Project.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Project.kt index abc37a0a..3d0007dd 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Project.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Project.kt @@ -7,234 +7,361 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Project.Builder::class) @NoAutoDetect class Project +@JsonCreator private constructor( - private val id: JsonField, - private val orgId: JsonField, - private val name: JsonField, - private val created: JsonField, - private val deletedAt: JsonField, - private val userId: JsonField, - private val settings: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("settings") + @ExcludeMissing + private val settings: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the project */ + /** + * Unique identifier for the project + * + * @throws BraintrustInvalidDataException 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") - /** Unique id for the organization that the project belongs under */ - fun orgId(): String = orgId.getRequired("org_id") - - /** Name of the project */ + /** + * Name of the project + * + * @throws BraintrustInvalidDataException 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") - /** Date of project creation */ + /** + * Unique id for the organization that the project belongs under + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") + + /** + * Date of project creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Date of project deletion, or null if the project is still active */ + /** + * Date of project deletion, or null if the project is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun deletedAt(): Optional = Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Identifies the user who created the project */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun settings(): Optional = Optional.ofNullable(settings.getNullable("settings")) - /** Unique identifier for the project */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Unique id for the organization that the project belongs under */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId - - /** Name of the project */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Date of project creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Date of project deletion, or null if the project is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt - - /** Identifies the user who created the project */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * Identifies the user who created the project + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - @JsonProperty("settings") @ExcludeMissing fun _settings() = settings + /** + * 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 [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 [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * Returns the raw JSON value of [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settings") @ExcludeMissing fun _settings(): JsonField = settings + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Project = apply { - if (!validated) { - id() - orgId() - name() - created() - deletedAt() - userId() - settings().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Project = apply { + if (validated) { + return@apply } - return other is Project && - this.id == other.id && - this.orgId == other.orgId && - this.name == other.name && - this.created == other.created && - this.deletedAt == other.deletedAt && - this.userId == other.userId && - this.settings == other.settings && - this.additionalProperties == other.additionalProperties + id() + name() + orgId() + created() + deletedAt() + settings().ifPresent { it.validate() } + userId() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - orgId, - name, - created, - deletedAt, - userId, - settings, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Project{id=$id, orgId=$orgId, name=$name, created=$created, deletedAt=$deletedAt, userId=$userId, settings=$settings, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Project]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Project]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var orgId: JsonField? = null private var created: JsonField = JsonMissing.of() private var deletedAt: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() private var settings: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(project: Project) = apply { - this.id = project.id - this.orgId = project.orgId - this.name = project.name - this.created = project.created - this.deletedAt = project.deletedAt - this.userId = project.userId - this.settings = project.settings - additionalProperties(project.additionalProperties) + id = project.id + name = project.name + orgId = project.orgId + created = project.created + deletedAt = project.deletedAt + settings = project.settings + userId = project.userId + additionalProperties = project.additionalProperties.toMutableMap() } /** Unique identifier for the project */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the project */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Unique id for the organization that the project belongs under */ - fun orgId(orgId: String) = orgId(JsonField.of(orgId)) - - /** Unique id for the organization that the project belongs under */ - @JsonProperty("org_id") - @ExcludeMissing - fun orgId(orgId: JsonField) = apply { this.orgId = orgId } + /** + * 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 } /** Name of the project */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the project */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } - /** Date of project creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** Unique id for the organization that the project belongs under */ + fun orgId(orgId: String) = orgId(JsonField.of(orgId)) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgId(orgId: JsonField) = apply { this.orgId = orgId } /** Date of project creation */ - @JsonProperty("created") - @ExcludeMissing + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } /** Date of project deletion, or null if the project is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) - - /** Date of project deletion, or null if the project is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } - /** Identifies the user who created the project */ - fun userId(userId: String) = userId(JsonField.of(userId)) + fun settings(settings: ProjectSettings?) = settings(JsonField.ofNullable(settings)) + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [ProjectSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { this.settings = settings } /** Identifies the user who created the project */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - fun settings(settings: ProjectSettings) = settings(JsonField.of(settings)) + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - @JsonProperty("settings") - @ExcludeMissing - fun settings(settings: JsonField) = apply { this.settings = settings } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Project]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .orgId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Project = Project( - id, - orgId, - name, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("orgId", orgId), created, deletedAt, - userId, settings, - additionalProperties.toUnmodifiable(), + userId, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Project && id == other.id && name == other.name && orgId == other.orgId && created == other.created && deletedAt == other.deletedAt && settings == other.settings && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, orgId, created, deletedAt, settings, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Project{id=$id, name=$name, orgId=$orgId, created=$created, deletedAt=$deletedAt, settings=$settings, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectCreateParams.kt index 6a037704..25f67ec7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectCreateParams.kt @@ -3,276 +3,461 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new project. If there is an existing project with the same name as the one specified in + * the request, will return the existing project unmodified + */ class ProjectCreateParams -constructor( - private val name: String, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): ProjectCreateBody { - return ProjectCreateBody( - name, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the project + * + * @throws BraintrustInvalidDataException 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() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * project belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ProjectCreateBody.Builder::class) @NoAutoDetect - class ProjectCreateBody - internal constructor( - private val name: String?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the project + * + * @throws BraintrustInvalidDataException 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") /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the project belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * 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 [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectCreateBody && - this.name == other.name && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties + name() + orgName() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - orgName, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectCreateBody{name=$name, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null + private var name: JsonField? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectCreateBody: ProjectCreateBody) = apply { - this.name = projectCreateBody.name - this.orgName = projectCreateBody.orgName - additionalProperties(projectCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the project belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectCreateBody = - ProjectCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * 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), orgName, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectCreateParams && - this.name == other.name && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectCreateParams{name=$name, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectCreateParams: ProjectCreateParams) = apply { - this.name = projectCreateParams.name - this.orgName = projectCreateParams.orgName - additionalQueryParams(projectCreateParams.additionalQueryParams) - additionalHeaders(projectCreateParams.additionalHeaders) - additionalBodyProperties(projectCreateParams.additionalBodyProperties) + body = projectCreateParams.body.toBuilder() + additionalHeaders = projectCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectCreateParams.additionalQueryParams.toBuilder() } /** Name of the project */ - fun name(name: String) = apply { this.name = 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) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the project belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectCreateParams]. + * + * 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(): ProjectCreateParams = ProjectCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectDeleteParams.kt index 830d84e9..d5ac8442 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a project object by its id */ class ProjectDeleteParams -constructor( +private constructor( private val projectId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Project id */ fun projectId(): String = projectId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectDeleteParams && - this.projectId == other.projectId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - projectId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "ProjectDeleteParams{projectId=$projectId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectDeleteParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectDeleteParams: ProjectDeleteParams) = apply { - this.projectId = projectDeleteParams.projectId - additionalQueryParams(projectDeleteParams.additionalQueryParams) - additionalHeaders(projectDeleteParams.additionalHeaders) - additionalBodyProperties(projectDeleteParams.additionalBodyProperties) + projectId = projectDeleteParams.projectId + additionalHeaders = projectDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = projectDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = projectDeleteParams.additionalBodyProperties.toMutableMap() } /** Project id */ fun projectId(projectId: String) = apply { this.projectId = projectId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [ProjectDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectDeleteParams = ProjectDeleteParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectId", projectId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectDeleteParams && projectId == other.projectId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "ProjectDeleteParams{projectId=$projectId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPage.kt index 11d4f3b9..1d934cf4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ProjectService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all projects. The projects are sorted by creation date, with the most recently-created + * projects coming first + */ class ProjectListPage private constructor( private val projectsService: ProjectService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ProjectListPage && - this.projectsService == other.projectsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectListPage && projectsService == other.projectsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectsService, params, response) /* spotless:on */ override fun toString() = "ProjectListPage{projectsService=$projectsService, params=$params, response=$response}" @@ -87,23 +84,18 @@ private constructor( @JvmStatic fun of(projectsService: ProjectService, params: ProjectListParams, response: Response) = - ProjectListPage( - projectsService, - params, - response, - ) + ProjectListPage(projectsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -113,11 +105,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -127,20 +123,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ProjectListPage]. */ @JvmStatic fun builder() = Builder() } @@ -157,22 +150,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectListPage, - ) : Iterable { + class AutoPager(private val firstPage: ProjectListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -181,7 +174,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPageAsync.kt index 15bb897c..f206043f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ProjectServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all projects. The projects are sorted by creation date, with the most recently-created + * projects coming first + */ class ProjectListPageAsync private constructor( private val projectsService: ProjectServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ProjectListPageAsync && - this.projectsService == other.projectsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectListPageAsync && projectsService == other.projectsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectsService, params, response) /* spotless:on */ override fun toString() = "ProjectListPageAsync{projectsService=$projectsService, params=$params, response=$response}" @@ -92,25 +88,19 @@ private constructor( fun of( projectsService: ProjectServiceAsync, params: ProjectListParams, - response: Response - ) = - ProjectListPageAsync( - projectsService, - params, - response, - ) + response: Response, + ) = ProjectListPageAsync(projectsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +110,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +128,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ProjectListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -164,27 +155,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectListPageAsync, - ) { + class AutoPager(private val firstPage: ProjectListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Project) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +184,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListParams.kt index 9cd5e09b..6b30061c 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,91 +20,99 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all projects. The projects are sorted by creation date, with the most recently-created + * projects coming first + */ class ProjectListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val orgName: String?, private val projectName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectName == other.projectName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - projectName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectName=$projectName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectName?.let { put("project_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): ProjectListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ProjectListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null @@ -111,19 +120,19 @@ constructor( private var orgName: String? = null private var projectName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectListParams: ProjectListParams) = apply { - this.endingBefore = projectListParams.endingBefore - this.ids = projectListParams.ids - this.limit = projectListParams.limit - this.orgName = projectListParams.orgName - this.projectName = projectListParams.projectName - this.startingAfter = projectListParams.startingAfter - additionalQueryParams(projectListParams.additionalQueryParams) - additionalHeaders(projectListParams.additionalHeaders) + endingBefore = projectListParams.endingBefore + ids = projectListParams.ids + limit = projectListParams.limit + orgName = projectListParams.orgName + projectName = projectListParams.projectName + startingAfter = projectListParams.startingAfter + additionalHeaders = projectListParams.additionalHeaders.toBuilder() + additionalQueryParams = projectListParams.additionalQueryParams.toBuilder() } /** @@ -133,34 +142,50 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** * Pagination cursor id. @@ -169,48 +194,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ProjectListParams = ProjectListParams( endingBefore, @@ -219,11 +311,15 @@ constructor( orgName, projectName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -233,8 +329,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -257,35 +351,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -294,21 +376,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -320,12 +413,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -336,4 +429,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && projectName == other.projectName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, projectName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectName=$projectName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParams.kt index 5d6b1011..13ea4533 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParams.kt @@ -3,37 +3,62 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects +/** Log feedback for a set of project logs events */ class ProjectLogFeedbackParams -constructor( +private constructor( private val projectId: String, - private val feedback: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId - fun feedback(): List = feedback + /** + * A list of project logs feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = body.feedback() - @JvmSynthetic - internal fun getBody(): ProjectLogFeedbackBody { - return ProjectLogFeedbackBody(feedback, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _feedback(): JsonField> = body._feedback() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -42,221 +67,364 @@ constructor( } } - @JsonDeserialize(builder = ProjectLogFeedbackBody.Builder::class) @NoAutoDetect - class ProjectLogFeedbackBody - internal constructor( - private val feedback: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("feedback") + @ExcludeMissing + private val feedback: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of project logs feedback items */ - @JsonProperty("feedback") fun feedback(): List? = feedback + /** + * A list of project logs feedback items + * + * @throws BraintrustInvalidDataException 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 feedback(): List = feedback.getRequired("feedback") + + /** + * Returns the raw JSON value of [feedback]. + * + * Unlike [feedback], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("feedback") + @ExcludeMissing + fun _feedback(): JsonField> = feedback @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectLogFeedbackBody && - this.feedback == other.feedback && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(feedback, additionalProperties) - } - return hashCode + feedback().forEach { it.validate() } + validated = true } - override fun toString() = - "ProjectLogFeedbackBody{feedback=$feedback, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var feedback: List? = null + private var feedback: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectLogFeedbackBody: ProjectLogFeedbackBody) = apply { - this.feedback = projectLogFeedbackBody.feedback - additionalProperties(projectLogFeedbackBody.additionalProperties) + internal fun from(body: Body) = apply { + feedback = body.feedback.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of project logs feedback items */ - @JsonProperty("feedback") - fun feedback(feedback: List) = apply { - this.feedback = feedback + fun feedback(feedback: List) = feedback(JsonField.of(feedback)) + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + this.feedback = feedback.map { it.toMutableList() } + } + + /** + * Adds a single [FeedbackProjectLogsItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackProjectLogsItem) = apply { + this.feedback = + (this.feedback ?: JsonField.of(mutableListOf())).also { + checkKnown("feedback", it).add(feedback) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectLogFeedbackBody = - ProjectLogFeedbackBody( - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("feedback", feedback).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && feedback == other.feedback && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectLogFeedbackParams && - this.projectId == other.projectId && - this.feedback == other.feedback && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(feedback, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectId, - feedback, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectLogFeedbackParams{projectId=$projectId, feedback=$feedback, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{feedback=$feedback, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectLogFeedbackParams]. + * + * The following fields are required: + * ```java + * .projectId() + * .feedback() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectLogFeedbackParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var feedback: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectLogFeedbackParams: ProjectLogFeedbackParams) = apply { - this.projectId = projectLogFeedbackParams.projectId - this.feedback(projectLogFeedbackParams.feedback) - additionalQueryParams(projectLogFeedbackParams.additionalQueryParams) - additionalHeaders(projectLogFeedbackParams.additionalHeaders) - additionalBodyProperties(projectLogFeedbackParams.additionalBodyProperties) + projectId = projectLogFeedbackParams.projectId + body = projectLogFeedbackParams.body.toBuilder() + additionalHeaders = projectLogFeedbackParams.additionalHeaders.toBuilder() + additionalQueryParams = projectLogFeedbackParams.additionalQueryParams.toBuilder() } /** Project id */ fun projectId(projectId: String) = apply { this.projectId = projectId } /** A list of project logs feedback items */ - fun feedback(feedback: List) = apply { - this.feedback.clear() - this.feedback.addAll(feedback) + fun feedback(feedback: List) = apply { body.feedback(feedback) } + + /** + * Sets [Builder.feedback] to an arbitrary JSON value. + * + * You should usually call [Builder.feedback] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun feedback(feedback: JsonField>) = apply { + body.feedback(feedback) } - /** A list of project logs feedback items */ - fun addFeedback(feedback: FeedbackProjectLogsItem) = apply { this.feedback.add(feedback) } + /** + * Adds a single [FeedbackProjectLogsItem] to [Builder.feedback]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFeedback(feedback: FeedbackProjectLogsItem) = apply { body.addFeedback(feedback) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectLogFeedbackParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * .feedback() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectLogFeedbackParams = ProjectLogFeedbackParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(feedback) { "`feedback` is required but was not set" } - .toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectId", projectId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectLogFeedbackParams && projectId == other.projectId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectLogFeedbackParams{projectId=$projectId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchParams.kt index 75f643a0..a3629afc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchParams.kt @@ -3,44 +3,101 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in a project logs. Equivalent to the POST form of the same path, but with the + * parameters in the URL query rather than in the request body. For more complex queries, use the + * `POST /btql` endpoint. + */ class ProjectLogFetchParams -constructor( +private constructor( private val projectId: String, private val limit: Long?, private val maxRootSpanId: String?, private val maxXactId: String?, private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + */ fun limit(): Optional = Optional.ofNullable(limit) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + */ fun maxXactId(): Optional = Optional.ofNullable(maxXactId) + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + */ fun version(): Optional = Optional.ofNullable(version) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.maxRootSpanId?.let { params.put("max_root_span_id", listOf(it.toString())) } - this.maxXactId?.let { params.put("max_xact_id", listOf(it.toString())) } - this.version?.let { params.put("version", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + limit?.let { put("limit", it.toString()) } + maxRootSpanId?.let { put("max_root_span_id", it) } + maxXactId?.let { put("max_xact_id", it) } + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -49,67 +106,42 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectLogFetchParams && - this.projectId == other.projectId && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - projectId, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectLogFetchParams{projectId=$projectId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectLogFetchParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectLogFetchParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null private var limit: Long? = null private var maxRootSpanId: String? = null private var maxXactId: String? = null private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectLogFetchParams: ProjectLogFetchParams) = apply { - this.projectId = projectLogFetchParams.projectId - this.limit = projectLogFetchParams.limit - this.maxRootSpanId = projectLogFetchParams.maxRootSpanId - this.maxXactId = projectLogFetchParams.maxXactId - this.version = projectLogFetchParams.version - additionalQueryParams(projectLogFetchParams.additionalQueryParams) - additionalHeaders(projectLogFetchParams.additionalHeaders) + projectId = projectLogFetchParams.projectId + limit = projectLogFetchParams.limit + maxRootSpanId = projectLogFetchParams.maxRootSpanId + maxXactId = projectLogFetchParams.maxXactId + version = projectLogFetchParams.version + additionalHeaders = projectLogFetchParams.additionalHeaders.toBuilder() + additionalQueryParams = projectLogFetchParams.additionalQueryParams.toBuilder() } /** Project id */ @@ -130,7 +162,17 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -144,7 +186,11 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { this.maxRootSpanId = maxRootSpanId } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -158,7 +204,10 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { this.maxXactId = maxXactId } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) /** * Retrieve a snapshot of events from a past time @@ -166,57 +215,143 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { this.version = version } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectLogFetchParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectLogFetchParams = ProjectLogFetchParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, + checkRequired("projectId", projectId), limit, maxRootSpanId, maxXactId, version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectLogFetchParams && projectId == other.projectId && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, limit, maxRootSpanId, maxXactId, version, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectLogFetchParams{projectId=$projectId, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParams.kt index fe4aed35..6b1ffba5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParams.kt @@ -3,61 +3,162 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Fetch the events in a project logs. Equivalent to the GET form of the same path, but with the + * parameters in the request body rather than in the URL query. For more complex queries, use the + * `POST /btql` endpoint. + */ class ProjectLogFetchPostParams -constructor( +private constructor( private val projectId: String, - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId - fun cursor(): Optional = Optional.ofNullable(cursor) - - fun filters(): Optional> = Optional.ofNullable(filters) - - fun limit(): Optional = Optional.ofNullable(limit) - - fun maxRootSpanId(): Optional = Optional.ofNullable(maxRootSpanId) - - fun maxXactId(): Optional = Optional.ofNullable(maxXactId) - - fun version(): Optional = Optional.ofNullable(version) - - @JvmSynthetic - internal fun getBody(): ProjectLogFetchPostBody { - return ProjectLogFetchPostBody( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * An opaque string to be used as a cursor for the next page of results, in order from latest to + * earliest. + * + * The string can be obtained directly from the `cursor` property of the previous fetch query + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun cursor(): Optional = body.cursor() + + /** + * limit the number of traces fetched + * + * Fetch queries may be paginated if the total result size is expected to be large (e.g. + * project_logs which accumulate over a long time). Note that fetch queries only support + * pagination in descending time order (from latest to earliest `_xact_id`. Furthermore, later + * pages may return rows which showed up in earlier pages, except with an earlier `_xact_id`. + * This happens because pagination occurs over the whole version history of the event log. You + * will most likely want to exclude any such duplicate, outdated rows (by `id`) from your + * combined result set. + * + * The `limit` parameter controls the number of full traces to return. So you may end up with + * more individual rows than the specified limit if you are fetching events containing traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun limit(): Optional = body.limit() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxRootSpanId(): Optional = body.maxRootSpanId() + + /** + * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of the + * explicit 'cursor' returned by object fetch requests. Please prefer the 'cursor' argument + * going forwards. + * + * Together, `max_xact_id` and `max_root_span_id` form a pagination cursor + * + * Since a paginated fetch query returns results in order from latest to earliest, the cursor + * for the next page can be found as the row with the minimum (earliest) value of the tuple + * `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of paginating + * fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun maxXactId(): Optional = body.maxXactId() + + /** + * Retrieve a snapshot of events from a past time + * + * The version id is essentially a filter on the latest event transaction id. You can use the + * `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun version(): Optional = body.version() + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _cursor(): JsonField = body._cursor() + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _limit(): JsonField = body._limit() + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxRootSpanId(): JsonField = body._maxRootSpanId() + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _maxXactId(): JsonField = body._maxXactId() + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _version(): JsonField = body._version() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -66,39 +167,40 @@ constructor( } } - @JsonDeserialize(builder = ProjectLogFetchPostBody.Builder::class) @NoAutoDetect - class ProjectLogFetchPostBody - internal constructor( - private val cursor: String?, - private val filters: List?, - private val limit: Long?, - private val maxRootSpanId: String?, - private val maxXactId: String?, - private val version: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("cursor") + @ExcludeMissing + private val cursor: JsonField = JsonMissing.of(), + @JsonProperty("limit") + @ExcludeMissing + private val limit: JsonField = JsonMissing.of(), + @JsonProperty("max_root_span_id") + @ExcludeMissing + private val maxRootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("max_xact_id") + @ExcludeMissing + private val maxXactId: JsonField = JsonMissing.of(), + @JsonProperty("version") + @ExcludeMissing + private val version: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * An opaque string to be used as a cursor for the next page of results, in order from * latest to earliest. * * The string can be obtained directly from the `cursor` property of the previous fetch * query - */ - @JsonProperty("cursor") fun cursor(): String? = cursor - - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("filters") fun filters(): List? = filters + fun cursor(): Optional = Optional.ofNullable(cursor.getNullable("cursor")) /** * limit the number of traces fetched @@ -114,8 +216,11 @@ constructor( * The `limit` parameter controls the number of full traces to return. So you may end up * with more individual rows than the specified limit if you are fetching events containing * traces. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("limit") fun limit(): Long? = limit + fun limit(): Optional = Optional.ofNullable(limit.getNullable("limit")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -128,8 +233,12 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_root_span_id") fun maxRootSpanId(): String? = maxRootSpanId + fun maxRootSpanId(): Optional = + Optional.ofNullable(maxRootSpanId.getNullable("max_root_span_id")) /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -142,81 +251,107 @@ constructor( * cursor for the next page can be found as the row with the minimum (earliest) value of the * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("max_xact_id") fun maxXactId(): String? = maxXactId + fun maxXactId(): Optional = + Optional.ofNullable(maxXactId.getNullable("max_xact_id")) /** * Retrieve a snapshot of events from a past time * * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun version(): Optional = Optional.ofNullable(version.getNullable("version")) + + /** + * Returns the raw JSON value of [cursor]. + * + * Unlike [cursor], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cursor") @ExcludeMissing fun _cursor(): JsonField = cursor + + /** + * Returns the raw JSON value of [limit]. + * + * Unlike [limit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("limit") @ExcludeMissing fun _limit(): JsonField = limit + + /** + * Returns the raw JSON value of [maxRootSpanId]. + * + * Unlike [maxRootSpanId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_root_span_id") + @ExcludeMissing + fun _maxRootSpanId(): JsonField = maxRootSpanId + + /** + * Returns the raw JSON value of [maxXactId]. + * + * Unlike [maxXactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("max_xact_id") @ExcludeMissing fun _maxXactId(): JsonField = maxXactId + + /** + * Returns the raw JSON value of [version]. + * + * Unlike [version], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("version") fun version(): String? = version + @JsonProperty("version") @ExcludeMissing fun _version(): JsonField = version @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectLogFetchPostBody && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalProperties, - ) - } - return hashCode + cursor() + limit() + maxRootSpanId() + maxXactId() + version() + validated = true } - override fun toString() = - "ProjectLogFetchPostBody{cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var cursor: String? = null - private var filters: List? = null - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null + private var cursor: JsonField = JsonMissing.of() + private var limit: JsonField = JsonMissing.of() + private var maxRootSpanId: JsonField = JsonMissing.of() + private var maxXactId: JsonField = JsonMissing.of() + private var version: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectLogFetchPostBody: ProjectLogFetchPostBody) = apply { - this.cursor = projectLogFetchPostBody.cursor - this.filters = projectLogFetchPostBody.filters - this.limit = projectLogFetchPostBody.limit - this.maxRootSpanId = projectLogFetchPostBody.maxRootSpanId - this.maxXactId = projectLogFetchPostBody.maxXactId - this.version = projectLogFetchPostBody.version - additionalProperties(projectLogFetchPostBody.additionalProperties) + internal fun from(body: Body) = apply { + cursor = body.cursor + limit = body.limit + maxRootSpanId = body.maxRootSpanId + maxXactId = body.maxXactId + version = body.version + additionalProperties = body.additionalProperties.toMutableMap() } /** @@ -226,18 +361,19 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - @JsonProperty("cursor") fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = cursor(JsonField.ofNullable(cursor)) + + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters - * are supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("filters") - fun filters(filters: List) = apply { this.filters = filters } + fun cursor(cursor: JsonField) = apply { this.cursor = cursor } /** * limit the number of traces fetched @@ -254,7 +390,26 @@ constructor( * with more individual rows than the specified limit if you are fetching events * containing traces. */ - @JsonProperty("limit") fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = limit(JsonField.ofNullable(limit)) + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun limit(limit: JsonField) = apply { this.limit = limit } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -268,8 +423,23 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_root_span_id") - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = + maxRootSpanId(JsonField.ofNullable(maxRootSpanId)) + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + this.maxRootSpanId = maxRootSpanId + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor @@ -283,8 +453,19 @@ constructor( * the tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an * overview of paginating fetch queries. */ - @JsonProperty("max_xact_id") - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = maxXactId(JsonField.ofNullable(maxXactId)) + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxXactId(maxXactId: JsonField) = apply { this.maxXactId = maxXactId } /** * Retrieve a snapshot of events from a past time @@ -293,110 +474,103 @@ constructor( * use the `max_xact_id` returned by a past fetch as the version to reproduce that exact * fetch. */ - @JsonProperty("version") fun version(version: String) = apply { this.version = version } + fun version(version: String?) = version(JsonField.ofNullable(version)) + + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun version(version: JsonField) = apply { this.version = version } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectLogFetchPostBody = - ProjectLogFetchPostBody( + 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. + */ + fun build(): Body = + Body( cursor, - filters?.toUnmodifiable(), limit, maxRootSpanId, maxXactId, version, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && cursor == other.cursor && limit == other.limit && maxRootSpanId == other.maxRootSpanId && maxXactId == other.maxXactId && version == other.version && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectLogFetchPostParams && - this.projectId == other.projectId && - this.cursor == other.cursor && - this.filters == other.filters && - this.limit == other.limit && - this.maxRootSpanId == other.maxRootSpanId && - this.maxXactId == other.maxXactId && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(cursor, limit, maxRootSpanId, maxXactId, version, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectId, - cursor, - filters, - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectLogFetchPostParams{projectId=$projectId, cursor=$cursor, filters=$filters, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{cursor=$cursor, limit=$limit, maxRootSpanId=$maxRootSpanId, maxXactId=$maxXactId, version=$version, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectLogFetchPostParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectLogFetchPostParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var cursor: String? = null - private var filters: MutableList = mutableListOf() - private var limit: Long? = null - private var maxRootSpanId: String? = null - private var maxXactId: String? = null - private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectLogFetchPostParams: ProjectLogFetchPostParams) = apply { - this.projectId = projectLogFetchPostParams.projectId - this.cursor = projectLogFetchPostParams.cursor - this.filters(projectLogFetchPostParams.filters ?: listOf()) - this.limit = projectLogFetchPostParams.limit - this.maxRootSpanId = projectLogFetchPostParams.maxRootSpanId - this.maxXactId = projectLogFetchPostParams.maxXactId - this.version = projectLogFetchPostParams.version - additionalQueryParams(projectLogFetchPostParams.additionalQueryParams) - additionalHeaders(projectLogFetchPostParams.additionalHeaders) - additionalBodyProperties(projectLogFetchPostParams.additionalBodyProperties) + projectId = projectLogFetchPostParams.projectId + body = projectLogFetchPostParams.body.toBuilder() + additionalHeaders = projectLogFetchPostParams.additionalHeaders.toBuilder() + additionalQueryParams = projectLogFetchPostParams.additionalQueryParams.toBuilder() } /** Project id */ @@ -409,30 +583,18 @@ constructor( * The string can be obtained directly from the `cursor` property of the previous fetch * query */ - fun cursor(cursor: String) = apply { this.cursor = cursor } + fun cursor(cursor: String?) = apply { body.cursor(cursor) } - /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. - * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. - */ - fun filters(filters: List) = apply { - this.filters.clear() - this.filters.addAll(filters) - } + /** Alias for calling [Builder.cursor] with `cursor.orElse(null)`. */ + fun cursor(cursor: Optional) = cursor(cursor.getOrNull()) /** - * NOTE: This parameter is deprecated and will be removed in a future revision. Consider - * using the `/btql` endpoint (https://www.braintrust.dev/docs/reference/btql) for more - * advanced filtering. + * Sets [Builder.cursor] to an arbitrary JSON value. * - * A list of filters on the events to fetch. Currently, only path-lookup type filters are - * supported. + * You should usually call [Builder.cursor] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun addFilter(filter: PathLookupFilter) = apply { this.filters.add(filter) } + fun cursor(cursor: JsonField) = apply { body.cursor(cursor) } /** * limit the number of traces fetched @@ -449,7 +611,25 @@ constructor( * with more individual rows than the specified limit if you are fetching events containing * traces. */ - fun limit(limit: Long) = apply { this.limit = limit } + fun limit(limit: Long?) = apply { body.limit(limit) } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** + * Sets [Builder.limit] to an arbitrary JSON value. + * + * You should usually call [Builder.limit] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun limit(limit: JsonField) = apply { body.limit(limit) } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -463,7 +643,22 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxRootSpanId(maxRootSpanId: String) = apply { this.maxRootSpanId = maxRootSpanId } + fun maxRootSpanId(maxRootSpanId: String?) = apply { body.maxRootSpanId(maxRootSpanId) } + + /** Alias for calling [Builder.maxRootSpanId] with `maxRootSpanId.orElse(null)`. */ + fun maxRootSpanId(maxRootSpanId: Optional) = + maxRootSpanId(maxRootSpanId.getOrNull()) + + /** + * Sets [Builder.maxRootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxRootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxRootSpanId(maxRootSpanId: JsonField) = apply { + body.maxRootSpanId(maxRootSpanId) + } /** * DEPRECATION NOTICE: The manually-constructed pagination cursor is deprecated in favor of @@ -477,7 +672,19 @@ constructor( * tuple `(_xact_id, root_span_id)`. See the documentation of `limit` for an overview of * paginating fetch queries. */ - fun maxXactId(maxXactId: String) = apply { this.maxXactId = maxXactId } + fun maxXactId(maxXactId: String?) = apply { body.maxXactId(maxXactId) } + + /** Alias for calling [Builder.maxXactId] with `maxXactId.orElse(null)`. */ + fun maxXactId(maxXactId: Optional) = maxXactId(maxXactId.getOrNull()) + + /** + * Sets [Builder.maxXactId] to an arbitrary JSON value. + * + * You should usually call [Builder.maxXactId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun maxXactId(maxXactId: JsonField) = apply { body.maxXactId(maxXactId) } /** * Retrieve a snapshot of events from a past time @@ -485,74 +692,167 @@ constructor( * The version id is essentially a filter on the latest event transaction id. You can use * the `max_xact_id` returned by a past fetch as the version to reproduce that exact fetch. */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { body.version(version) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + /** + * Sets [Builder.version] to an arbitrary JSON value. + * + * You should usually call [Builder.version] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun version(version: JsonField) = apply { body.version(version) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectLogFetchPostParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectLogFetchPostParams = ProjectLogFetchPostParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - cursor, - if (filters.size == 0) null else filters.toUnmodifiable(), - limit, - maxRootSpanId, - maxXactId, - version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectId", projectId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectLogFetchPostParams && projectId == other.projectId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectLogFetchPostParams{projectId=$projectId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogInsertParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogInsertParams.kt index abe096e9..629a3f65 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogInsertParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogInsertParams.kt @@ -2,49 +2,63 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.BaseDeserializer -import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects -import java.util.Optional +/** Insert a set of events into the project logs */ class ProjectLogInsertParams -constructor( +private constructor( private val projectId: String, - private val events: List, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId - fun events(): List = events + /** + * A list of project logs events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = body.events() - @JvmSynthetic - internal fun getBody(): ProjectLogInsertBody { - return ProjectLogInsertBody(events, additionalBodyProperties) - } + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _events(): JsonField> = body._events() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + @JvmSynthetic internal fun _body(): Body = body - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -53,360 +67,361 @@ constructor( } } - @JsonDeserialize(builder = ProjectLogInsertBody.Builder::class) @NoAutoDetect - class ProjectLogInsertBody - internal constructor( - private val events: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("events") + @ExcludeMissing + private val events: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** A list of project logs events to insert */ - @JsonProperty("events") fun events(): List? = events + /** + * A list of project logs events to insert + * + * @throws BraintrustInvalidDataException 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 events(): List = events.getRequired("events") + + /** + * Returns the raw JSON value of [events]. + * + * Unlike [events], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("events") + @ExcludeMissing + fun _events(): JsonField> = events @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectLogInsertBody && - this.events == other.events && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(events, additionalProperties) - } - return hashCode + events().forEach { it.validate() } + validated = true } - override fun toString() = - "ProjectLogInsertBody{events=$events, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var events: List? = null + private var events: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectLogInsertBody: ProjectLogInsertBody) = apply { - this.events = projectLogInsertBody.events - additionalProperties(projectLogInsertBody.additionalProperties) + internal fun from(body: Body) = apply { + events = body.events.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of project logs events to insert */ - @JsonProperty("events") fun events(events: List) = apply { this.events = events } + fun events(events: List) = events(JsonField.of(events)) + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun events(events: JsonField>) = apply { + this.events = events.map { it.toMutableList() } + } + + /** + * Adds a single [InsertProjectLogsEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertProjectLogsEvent) = apply { + events = + (events ?: JsonField.of(mutableListOf())).also { + checkKnown("events", it).add(event) + } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectLogInsertBody = - ProjectLogInsertBody( - checkNotNull(events) { "`events` is required but was not set" } - .toUnmodifiable(), - additionalProperties.toUnmodifiable() - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("events", events).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && events == other.events && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectLogInsertParams && - this.projectId == other.projectId && - this.events == other.events && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(events, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectId, - events, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectLogInsertParams{projectId=$projectId, events=$events, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = "Body{events=$events, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectLogInsertParams]. + * + * The following fields are required: + * ```java + * .projectId() + * .events() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectLogInsertParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var events: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectLogInsertParams: ProjectLogInsertParams) = apply { - this.projectId = projectLogInsertParams.projectId - this.events(projectLogInsertParams.events) - additionalQueryParams(projectLogInsertParams.additionalQueryParams) - additionalHeaders(projectLogInsertParams.additionalHeaders) - additionalBodyProperties(projectLogInsertParams.additionalBodyProperties) + projectId = projectLogInsertParams.projectId + body = projectLogInsertParams.body.toBuilder() + additionalHeaders = projectLogInsertParams.additionalHeaders.toBuilder() + additionalQueryParams = projectLogInsertParams.additionalQueryParams.toBuilder() } /** Project id */ fun projectId(projectId: String) = apply { this.projectId = projectId } /** A list of project logs events to insert */ - fun events(events: List) = apply { - this.events.clear() - this.events.addAll(events) - } + fun events(events: List) = apply { body.events(events) } + + /** + * Sets [Builder.events] to an arbitrary JSON value. + * + * You should usually call [Builder.events] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun events(events: JsonField>) = apply { body.events(events) } + + /** + * Adds a single [InsertProjectLogsEvent] to [events]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addEvent(event: InsertProjectLogsEvent) = apply { body.addEvent(event) } - /** A list of project logs events to insert */ - fun addEvent(event: Event) = apply { this.events.add(event) } - - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): ProjectLogInsertParams = - ProjectLogInsertParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(events) { "`events` is required but was not set" }.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(using = Event.Deserializer::class) - @JsonSerialize(using = Event.Serializer::class) - class Event - private constructor( - private val insertProjectLogsEventReplace: InsertProjectLogsEventReplace? = null, - private val insertProjectLogsEventMerge: InsertProjectLogsEventMerge? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - fun insertProjectLogsEventReplace(): Optional = - Optional.ofNullable(insertProjectLogsEventReplace) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun insertProjectLogsEventMerge(): Optional = - Optional.ofNullable(insertProjectLogsEventMerge) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - fun isInsertProjectLogsEventReplace(): Boolean = insertProjectLogsEventReplace != null + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - fun isInsertProjectLogsEventMerge(): Boolean = insertProjectLogsEventMerge != null + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - fun asInsertProjectLogsEventReplace(): InsertProjectLogsEventReplace = - insertProjectLogsEventReplace.getOrThrow("insertProjectLogsEventReplace") + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun asInsertProjectLogsEventMerge(): InsertProjectLogsEventMerge = - insertProjectLogsEventMerge.getOrThrow("insertProjectLogsEventMerge") + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun _json(): Optional = Optional.ofNullable(_json) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - fun accept(visitor: Visitor): T { - return when { - insertProjectLogsEventReplace != null -> - visitor.visitInsertProjectLogsEventReplace(insertProjectLogsEventReplace) - insertProjectLogsEventMerge != null -> - visitor.visitInsertProjectLogsEventMerge(insertProjectLogsEventMerge) - else -> visitor.unknown(_json) - } + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun validate(): Event = apply { - if (!validated) { - if (insertProjectLogsEventReplace == null && insertProjectLogsEventMerge == null) { - throw BraintrustInvalidDataException("Unknown Event: $_json") - } - insertProjectLogsEventReplace?.validate() - insertProjectLogsEventMerge?.validate() - validated = true - } + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - return other is Event && - this.insertProjectLogsEventReplace == other.insertProjectLogsEventReplace && - this.insertProjectLogsEventMerge == other.insertProjectLogsEventMerge + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - override fun hashCode(): Int { - return Objects.hash(insertProjectLogsEventReplace, insertProjectLogsEventMerge) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - override fun toString(): String { - return when { - insertProjectLogsEventReplace != null -> - "Event{insertProjectLogsEventReplace=$insertProjectLogsEventReplace}" - insertProjectLogsEventMerge != null -> - "Event{insertProjectLogsEventMerge=$insertProjectLogsEventMerge}" - _json != null -> "Event{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Event") - } + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - companion object { + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmStatic - fun ofInsertProjectLogsEventReplace( - insertProjectLogsEventReplace: InsertProjectLogsEventReplace - ) = Event(insertProjectLogsEventReplace = insertProjectLogsEventReplace) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic - fun ofInsertProjectLogsEventMerge( - insertProjectLogsEventMerge: InsertProjectLogsEventMerge - ) = Event(insertProjectLogsEventMerge = insertProjectLogsEventMerge) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - interface Visitor { - - fun visitInsertProjectLogsEventReplace( - insertProjectLogsEventReplace: InsertProjectLogsEventReplace - ): T - - fun visitInsertProjectLogsEventMerge( - insertProjectLogsEventMerge: InsertProjectLogsEventMerge - ): T + /** + * Returns an immutable instance of [ProjectLogInsertParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * .events() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ProjectLogInsertParams = + ProjectLogInsertParams( + checkRequired("projectId", projectId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Event: $json") - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class Deserializer : BaseDeserializer(Event::class) { + return /* spotless:off */ other is ProjectLogInsertParams && projectId == other.projectId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - override fun ObjectCodec.deserialize(node: JsonNode): Event { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { - it.validate() - } - ?.let { - return Event(insertProjectLogsEventReplace = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { - it.validate() - } - ?.let { - return Event(insertProjectLogsEventMerge = it, _json = json) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - return Event(_json = json) - } - } - - class Serializer : BaseSerializer(Event::class) { - - override fun serialize( - value: Event, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.insertProjectLogsEventReplace != null -> - generator.writeObject(value.insertProjectLogsEventReplace) - value.insertProjectLogsEventMerge != null -> - generator.writeObject(value.insertProjectLogsEventMerge) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Event") - } - } - } - } + override fun toString() = + "ProjectLogInsertParams{projectId=$projectId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogsEvent.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogsEvent.kt index 7fec3828..f4371612 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogsEvent.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectLogsEvent.kt @@ -8,50 +8,82 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ProjectLogsEvent.Builder::class) @NoAutoDetect class ProjectLogsEvent +@JsonCreator private constructor( - private val id: JsonField, - private val _xactId: JsonField, - private val created: JsonField, - private val orgId: JsonField, - private val projectId: JsonField, - private val logId: JsonField, - private val input: JsonValue, - private val output: JsonValue, - private val expected: JsonValue, - private val error: JsonValue, - private val scores: JsonField, - private val metadata: JsonField, - private val tags: JsonField>, - private val metrics: JsonField, - private val context: JsonField, - private val spanId: JsonField, - private val spanParents: JsonField>, - private val rootSpanId: JsonField, - private val spanAttributes: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("log_id") @ExcludeMissing private val logId: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("root_span_id") + @ExcludeMissing + private val rootSpanId: JsonField = JsonMissing.of(), + @JsonProperty("span_id") + @ExcludeMissing + private val spanId: JsonField = JsonMissing.of(), + @JsonProperty("context") + @ExcludeMissing + private val context: JsonField = JsonMissing.of(), + @JsonProperty("error") @ExcludeMissing private val error: JsonValue = JsonMissing.of(), + @JsonProperty("expected") @ExcludeMissing private val expected: JsonValue = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing private val input: JsonValue = JsonMissing.of(), + @JsonProperty("is_root") + @ExcludeMissing + private val isRoot: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("metrics") + @ExcludeMissing + private val metrics: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("output") @ExcludeMissing private val output: JsonValue = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonProperty("span_attributes") + @ExcludeMissing + private val spanAttributes: JsonField = JsonMissing.of(), + @JsonProperty("span_parents") + @ExcludeMissing + private val spanParents: JsonField> = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * A unique identifier for the project logs event. If you don't provide one, BrainTrust will * generate one for you + * + * @throws BraintrustInvalidDataException 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") @@ -59,32 +91,74 @@ private constructor( * The transaction id of an event is unique to the network operation that processed the event * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve * a versioned snapshot of the project logs (see the `version` parameter) + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") - /** The timestamp the project logs event was created */ + /** + * The timestamp the project logs event was created + * + * @throws BraintrustInvalidDataException 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 created(): OffsetDateTime = created.getRequired("created") - /** Unique id for the organization that the project belongs under */ + /** + * A literal 'g' which identifies the log as a project log + * + * @throws BraintrustInvalidDataException 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 logId(): LogId = logId.getRequired("log_id") + + /** + * Unique id for the organization that the project belongs under + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") - /** Unique identifier for the project */ + /** + * Unique identifier for the project + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** A literal 'g' which identifies the log as a project log */ - fun logId(): LogId = logId.getRequired("log_id") + /** + * A unique identifier for the trace this project logs event belongs to + * + * @throws BraintrustInvalidDataException 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 rootSpanId(): String = rootSpanId.getRequired("root_span_id") - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - fun input(): JsonValue = input + /** + * A unique identifier used to link different project logs events together as part of a full + * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full + * details on tracing + * + * @throws BraintrustInvalidDataException 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 spanId(): String = spanId.getRequired("span_id") /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. + * Context is additional information about the code that produced the project logs event. It is + * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the + * location in code which produced the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun output(): JsonValue = output + fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + + /** The error that occurred, if any. */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonValue = error /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to @@ -94,21 +168,18 @@ private constructor( * analyses. However, we may later use these values to re-score outputs or fine-tune your * models. */ - fun expected(): JsonValue = expected + @JsonProperty("expected") @ExcludeMissing fun _expected(): JsonValue = expected - /** The error that occurred, if any. */ - fun error(): JsonValue = error + /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonValue = input /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. + * Whether this span is a root span + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) + fun isRoot(): Optional = Optional.ofNullable(isRoot.getNullable("is_root")) /** * A dictionary with additional data about the test example, model outputs, or just about @@ -116,294 +187,306 @@ private constructor( * example, you could log the `prompt`, example's `id`, or anything else that would be useful to * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - /** A list of tags to log */ - fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** * Metrics are numerical measurements tracking the execution of the code that produced the * project logs event. Use "start" and "end" to track the time span over which the project logs * event was produced + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event + * Indicates the event was copied from another object. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun context(): Optional = Optional.ofNullable(context.getNullable("context")) + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) /** - * A unique identifier used to link different project logs events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * The output of your application, including post-processing (an arbitrary, JSON serializable + * object), that allows you to determine whether the result is correct or not. For example, in + * an app that generates SQL queries, the `output` should be the _result_ of the SQL query + * generated by the model, not the query itself, because there may be multiple valid queries + * that answer a single question. */ - fun spanId(): String = spanId.getRequired("span_id") + @JsonProperty("output") @ExcludeMissing fun _output(): JsonValue = output /** - * An array of the parent `span_ids` of this project logs event. This should be empty for the - * root span of a trace, and should most often contain just one parent element for subspans + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety + * of signals that help you determine how accurate the outputs are compared to what you expect + * and diagnose failures. For example, a summarization app might have one score that tells you + * how accurate the summary is, and another that measures the word similarity between the + * generated and grouth truth summary. The word similarity score could help you determine + * whether the summarization was covering similar concepts or not. You can use these scores to + * help you sort, filter, and compare logs. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun spanParents(): Optional> = - Optional.ofNullable(spanParents.getNullable("span_parents")) - - /** The `span_id` of the root of the trace this project logs event belongs to */ - fun rootSpanId(): String = rootSpanId.getRequired("root_span_id") + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - /** Human-identifying attributes of the span, such as name, type, etc. */ + /** + * Human-identifying attributes of the span, such as name, type, etc. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun spanAttributes(): Optional = Optional.ofNullable(spanAttributes.getNullable("span_attributes")) /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you + * An array of the parent `span_ids` of this project logs event. This should be empty for the + * root span of a trace, and should most often contain just one parent element for subspans + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + fun spanParents(): Optional> = + Optional.ofNullable(spanParents.getNullable("span_parents")) /** - * The transaction id of an event is unique to the network operation that processed the event - * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve - * a versioned snapshot of the project logs (see the `version` parameter) + * A list of tags to log + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("_xact_id") @ExcludeMissing fun __xactId() = _xactId + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** The timestamp the project logs event was created */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 - /** Unique id for the organization that the project belongs under */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + /** + * Returns the raw JSON value of [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId - /** Unique identifier for the project */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** A literal 'g' which identifies the log as a project log */ - @JsonProperty("log_id") @ExcludeMissing fun _logId() = logId + /** + * Returns the raw JSON value of [logId]. + * + * Unlike [logId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("log_id") @ExcludeMissing fun _logId(): JsonField = logId - /** The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - @JsonProperty("input") @ExcludeMissing fun _input() = input + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId /** - * The output of your application, including post-processing (an arbitrary, JSON serializable - * object), that allows you to determine whether the result is correct or not. For example, in - * an app that generates SQL queries, the `output` should be the _result_ of the SQL query - * generated by the model, not the query itself, because there may be multiple valid queries - * that answer a single question. + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("output") @ExcludeMissing fun _output() = output + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId /** - * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to - * `output` to determine if your `output` value is correct or not. Braintrust currently does not - * compare `output` to `expected` for you, since there are so many different ways to do that - * correctly. Instead, these values are just used to help you navigate while digging into - * analyses. However, we may later use these values to re-score outputs or fine-tune your - * models. + * Returns the raw JSON value of [rootSpanId]. + * + * Unlike [rootSpanId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("expected") @ExcludeMissing fun _expected() = expected + @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId(): JsonField = rootSpanId - /** The error that occurred, if any. */ - @JsonProperty("error") @ExcludeMissing fun _error() = error + /** + * Returns the raw JSON value of [spanId]. + * + * Unlike [spanId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_id") @ExcludeMissing fun _spanId(): JsonField = spanId /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a variety - * of signals that help you determine how accurate the outputs are compared to what you expect - * and diagnose failures. For example, a summarization app might have one score that tells you - * how accurate the summary is, and another that measures the word similarity between the - * generated and grouth truth summary. The word similarity score could help you determine - * whether the summarization was covering similar concepts or not. You can use these scores to - * help you sort, filter, and compare logs. + * Returns the raw JSON value of [context]. + * + * Unlike [context], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores + @JsonProperty("context") @ExcludeMissing fun _context(): JsonField = context /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. For - * example, you could log the `prompt`, example's `id`, or anything else that would be useful to - * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys - * must be strings + * Returns the raw JSON value of [isRoot]. + * + * Unlike [isRoot], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + @JsonProperty("is_root") @ExcludeMissing fun _isRoot(): JsonField = isRoot - /** A list of tags to log */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project logs - * event was produced + * Returns the raw JSON value of [metrics]. + * + * Unlike [metrics], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics + @JsonProperty("metrics") @ExcludeMissing fun _metrics(): JsonField = metrics /** - * Context is additional information about the code that produced the project logs event. It is - * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the - * location in code which produced the project logs event + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("context") @ExcludeMissing fun _context() = context + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin /** - * A unique identifier used to link different project logs events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("span_id") @ExcludeMissing fun _spanId() = spanId + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores /** - * An array of the parent `span_ids` of this project logs event. This should be empty for the - * root span of a trace, and should most often contain just one parent element for subspans + * Returns the raw JSON value of [spanAttributes]. + * + * Unlike [spanAttributes], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("span_parents") @ExcludeMissing fun _spanParents() = spanParents + @JsonProperty("span_attributes") + @ExcludeMissing + fun _spanAttributes(): JsonField = spanAttributes - /** The `span_id` of the root of the trace this project logs event belongs to */ - @JsonProperty("root_span_id") @ExcludeMissing fun _rootSpanId() = rootSpanId + /** + * Returns the raw JSON value of [spanParents]. + * + * Unlike [spanParents], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("span_parents") + @ExcludeMissing + fun _spanParents(): JsonField> = spanParents - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") @ExcludeMissing fun _spanAttributes() = spanAttributes + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectLogsEvent = apply { - if (!validated) { - id() - _xactId() - created() - orgId() - projectId() - logId() - input() - output() - expected() - error() - scores().map { it.validate() } - metadata().map { it.validate() } - tags() - metrics().map { it.validate() } - context().map { it.validate() } - spanId() - spanParents() - rootSpanId() - spanAttributes().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectLogsEvent = apply { + if (validated) { + return@apply } - return other is ProjectLogsEvent && - this.id == other.id && - this._xactId == other._xactId && - this.created == other.created && - this.orgId == other.orgId && - this.projectId == other.projectId && - this.logId == other.logId && - this.input == other.input && - this.output == other.output && - this.expected == other.expected && - this.error == other.error && - this.scores == other.scores && - this.metadata == other.metadata && - this.tags == other.tags && - this.metrics == other.metrics && - this.context == other.context && - this.spanId == other.spanId && - this.spanParents == other.spanParents && - this.rootSpanId == other.rootSpanId && - this.spanAttributes == other.spanAttributes && - this.additionalProperties == other.additionalProperties + id() + _xactId() + created() + logId() + orgId() + projectId() + rootSpanId() + spanId() + context().ifPresent { it.validate() } + isRoot() + metadata().ifPresent { it.validate() } + metrics().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + scores().ifPresent { it.validate() } + spanAttributes().ifPresent { it.validate() } + spanParents() + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - _xactId, - created, - orgId, - projectId, - logId, - input, - output, - expected, - error, - scores, - metadata, - tags, - metrics, - context, - spanId, - spanParents, - rootSpanId, - spanAttributes, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectLogsEvent{id=$id, _xactId=$_xactId, created=$created, orgId=$orgId, projectId=$projectId, logId=$logId, input=$input, output=$output, expected=$expected, error=$error, scores=$scores, metadata=$metadata, tags=$tags, metrics=$metrics, context=$context, spanId=$spanId, spanParents=$spanParents, rootSpanId=$rootSpanId, spanAttributes=$spanAttributes, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectLogsEvent]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .logId() + * .orgId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var id: JsonField = JsonMissing.of() - private var _xactId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var logId: JsonField = JsonMissing.of() - private var input: JsonValue = JsonMissing.of() - private var output: JsonValue = JsonMissing.of() - private var expected: JsonValue = JsonMissing.of() + /** A builder for [ProjectLogsEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var created: JsonField? = null + private var logId: JsonField? = null + private var orgId: JsonField? = null + private var projectId: JsonField? = null + private var rootSpanId: JsonField? = null + private var spanId: JsonField? = null + private var context: JsonField = JsonMissing.of() private var error: JsonValue = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() + private var expected: JsonValue = JsonMissing.of() + private var input: JsonValue = JsonMissing.of() + private var isRoot: JsonField = JsonMissing.of() private var metadata: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() private var metrics: JsonField = JsonMissing.of() - private var context: JsonField = JsonMissing.of() - private var spanId: JsonField = JsonMissing.of() - private var spanParents: JsonField> = JsonMissing.of() - private var rootSpanId: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var output: JsonValue = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() private var spanAttributes: JsonField = JsonMissing.of() + private var spanParents: JsonField>? = null + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectLogsEvent: ProjectLogsEvent) = apply { - this.id = projectLogsEvent.id - this._xactId = projectLogsEvent._xactId - this.created = projectLogsEvent.created - this.orgId = projectLogsEvent.orgId - this.projectId = projectLogsEvent.projectId - this.logId = projectLogsEvent.logId - this.input = projectLogsEvent.input - this.output = projectLogsEvent.output - this.expected = projectLogsEvent.expected - this.error = projectLogsEvent.error - this.scores = projectLogsEvent.scores - this.metadata = projectLogsEvent.metadata - this.tags = projectLogsEvent.tags - this.metrics = projectLogsEvent.metrics - this.context = projectLogsEvent.context - this.spanId = projectLogsEvent.spanId - this.spanParents = projectLogsEvent.spanParents - this.rootSpanId = projectLogsEvent.rootSpanId - this.spanAttributes = projectLogsEvent.spanAttributes - additionalProperties(projectLogsEvent.additionalProperties) + id = projectLogsEvent.id + _xactId = projectLogsEvent._xactId + created = projectLogsEvent.created + logId = projectLogsEvent.logId + orgId = projectLogsEvent.orgId + projectId = projectLogsEvent.projectId + rootSpanId = projectLogsEvent.rootSpanId + spanId = projectLogsEvent.spanId + context = projectLogsEvent.context + error = projectLogsEvent.error + expected = projectLogsEvent.expected + input = projectLogsEvent.input + isRoot = projectLogsEvent.isRoot + metadata = projectLogsEvent.metadata + metrics = projectLogsEvent.metrics + origin = projectLogsEvent.origin + output = projectLogsEvent.output + scores = projectLogsEvent.scores + spanAttributes = projectLogsEvent.spanAttributes + spanParents = projectLogsEvent.spanParents.map { it.toMutableList() } + tags = projectLogsEvent.tags.map { it.toMutableList() } + additionalProperties = projectLogsEvent.additionalProperties.toMutableMap() } /** @@ -413,10 +496,12 @@ private constructor( fun id(id: String) = id(JsonField.of(id)) /** - * A unique identifier for the project logs event. If you don't provide one, BrainTrust will - * generate one for you + * 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. */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } + fun id(id: JsonField) = apply { this.id = id } /** * The transaction id of an event is unique to the network operation that processed the @@ -426,63 +511,106 @@ private constructor( fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) /** - * The transaction id of an event is unique to the network operation that processed the - * event insertion. Transaction ids are monotonically increasing over time and can be used - * to retrieve a versioned snapshot of the project logs (see the `version` parameter) + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("_xact_id") - @ExcludeMissing fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } /** The timestamp the project logs event was created */ fun created(created: OffsetDateTime) = created(JsonField.of(created)) - /** The timestamp the project logs event was created */ - @JsonProperty("created") - @ExcludeMissing + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } + /** A literal 'g' which identifies the log as a project log */ + fun logId(logId: LogId) = logId(JsonField.of(logId)) + + /** + * Sets [Builder.logId] to an arbitrary JSON value. + * + * You should usually call [Builder.logId] with a well-typed [LogId] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun logId(logId: JsonField) = apply { this.logId = logId } + /** Unique id for the organization that the project belongs under */ fun orgId(orgId: String) = orgId(JsonField.of(orgId)) - /** Unique id for the organization that the project belongs under */ - @JsonProperty("org_id") - @ExcludeMissing + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun orgId(orgId: JsonField) = apply { this.orgId = orgId } /** Unique identifier for the project */ fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Unique identifier for the project */ - @JsonProperty("project_id") - @ExcludeMissing + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - /** A literal 'g' which identifies the log as a project log */ - fun logId(logId: LogId) = logId(JsonField.of(logId)) + /** A unique identifier for the trace this project logs event belongs to */ + fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) - /** A literal 'g' which identifies the log as a project log */ - @JsonProperty("log_id") - @ExcludeMissing - fun logId(logId: JsonField) = apply { this.logId = logId } + /** + * Sets [Builder.rootSpanId] to an arbitrary JSON value. + * + * You should usually call [Builder.rootSpanId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } /** - * The arguments that uniquely define a user input (an arbitrary, JSON serializable object). + * A unique identifier used to link different project logs events together as part of a full + * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full + * details on tracing */ - @JsonProperty("input") - @ExcludeMissing - fun input(input: JsonValue) = apply { this.input = input } + fun spanId(spanId: String) = spanId(JsonField.of(spanId)) /** - * The output of your application, including post-processing (an arbitrary, JSON - * serializable object), that allows you to determine whether the result is correct or not. - * For example, in an app that generates SQL queries, the `output` should be the _result_ of - * the SQL query generated by the model, not the query itself, because there may be multiple - * valid queries that answer a single question. + * Sets [Builder.spanId] to an arbitrary JSON value. + * + * You should usually call [Builder.spanId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("output") - @ExcludeMissing - fun output(output: JsonValue) = apply { this.output = output } + fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + + /** + * Context is additional information about the code that produced the project logs event. It + * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to + * track the location in code which produced the project logs event + */ + fun context(context: Context?) = context(JsonField.ofNullable(context)) + + /** Alias for calling [Builder.context] with `context.orElse(null)`. */ + fun context(context: Optional) = context(context.getOrNull()) + + /** + * Sets [Builder.context] to an arbitrary JSON value. + * + * You should usually call [Builder.context] with a well-typed [Context] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun context(context: JsonField) = apply { this.context = context } + + /** The error that occurred, if any. */ + fun error(error: JsonValue) = apply { this.error = error } /** * The ground truth value (an arbitrary, JSON serializable object) that you'd compare to @@ -492,47 +620,33 @@ private constructor( * into analyses. However, we may later use these values to re-score outputs or fine-tune * your models. */ - @JsonProperty("expected") - @ExcludeMissing fun expected(expected: JsonValue) = apply { this.expected = expected } - /** The error that occurred, if any. */ - @JsonProperty("error") - @ExcludeMissing - fun error(error: JsonValue) = apply { this.error = error } - /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. + * The arguments that uniquely define a user input (an arbitrary, JSON serializable object). */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) + fun input(input: JsonValue) = apply { this.input = input } + + /** Whether this span is a root span */ + fun isRoot(isRoot: Boolean?) = isRoot(JsonField.ofNullable(isRoot)) /** - * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a - * variety of signals that help you determine how accurate the outputs are compared to what - * you expect and diagnose failures. For example, a summarization app might have one score - * that tells you how accurate the summary is, and another that measures the word similarity - * between the generated and grouth truth summary. The word similarity score could help you - * determine whether the summarization was covering similar concepts or not. You can use - * these scores to help you sort, filter, and compare logs. + * Alias for [Builder.isRoot]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } + fun isRoot(isRoot: Boolean) = isRoot(isRoot as Boolean?) + + /** Alias for calling [Builder.isRoot] with `isRoot.orElse(null)`. */ + fun isRoot(isRoot: Optional) = isRoot(isRoot.getOrNull()) /** - * A dictionary with additional data about the test example, model outputs, or just about - * anything else that's relevant, that you can use to help find and analyze examples later. - * For example, you could log the `prompt`, example's `id`, or anything else that would be - * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, - * but its keys must be strings + * Sets [Builder.isRoot] to an arbitrary JSON value. + * + * You should usually call [Builder.isRoot] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + fun isRoot(isRoot: JsonField) = apply { this.isRoot = isRoot } /** * A dictionary with additional data about the test example, model outputs, or just about @@ -541,191 +655,320 @@ private constructor( * useful to slice/dice later. The values in `metadata` can be any JSON-serializable type, * but its keys must be strings */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) - /** A list of tags to log */ - fun tags(tags: List) = tags(JsonField.of(tags)) + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) - /** A list of tags to log */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** * Metrics are numerical measurements tracking the execution of the code that produced the * project logs event. Use "start" and "end" to track the time span over which the project * logs event was produced */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) + fun metrics(metrics: Metrics?) = metrics(JsonField.ofNullable(metrics)) + + /** Alias for calling [Builder.metrics] with `metrics.orElse(null)`. */ + fun metrics(metrics: Optional) = metrics(metrics.getOrNull()) + + /** + * Sets [Builder.metrics] to an arbitrary JSON value. + * + * You should usually call [Builder.metrics] with a well-typed [Metrics] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + + /** Indicates the event was copied from another object. */ + fun origin(origin: ObjectReference?) = origin(JsonField.ofNullable(origin)) + + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) /** - * Metrics are numerical measurements tracking the execution of the code that produced the - * project logs event. Use "start" and "end" to track the time span over which the project - * logs event was produced + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [ObjectReference] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + fun origin(origin: JsonField) = apply { this.origin = origin } /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event + * The output of your application, including post-processing (an arbitrary, JSON + * serializable object), that allows you to determine whether the result is correct or not. + * For example, in an app that generates SQL queries, the `output` should be the _result_ of + * the SQL query generated by the model, not the query itself, because there may be multiple + * valid queries that answer a single question. */ - fun context(context: Context) = context(JsonField.of(context)) + fun output(output: JsonValue) = apply { this.output = output } /** - * Context is additional information about the code that produced the project logs event. It - * is essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to - * track the location in code which produced the project logs event + * A dictionary of numeric values (between 0 and 1) to log. The scores should give you a + * variety of signals that help you determine how accurate the outputs are compared to what + * you expect and diagnose failures. For example, a summarization app might have one score + * that tells you how accurate the summary is, and another that measures the word similarity + * between the generated and grouth truth summary. The word similarity score could help you + * determine whether the summarization was covering similar concepts or not. You can use + * these scores to help you sort, filter, and compare logs. */ - @JsonProperty("context") - @ExcludeMissing - fun context(context: JsonField) = apply { this.context = context } + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) + + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) /** - * A unique identifier used to link different project logs events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun spanId(spanId: String) = spanId(JsonField.of(spanId)) + fun scores(scores: JsonField) = apply { this.scores = scores } + + /** Human-identifying attributes of the span, such as name, type, etc. */ + fun spanAttributes(spanAttributes: SpanAttributes?) = + spanAttributes(JsonField.ofNullable(spanAttributes)) + + /** Alias for calling [Builder.spanAttributes] with `spanAttributes.orElse(null)`. */ + fun spanAttributes(spanAttributes: Optional) = + spanAttributes(spanAttributes.getOrNull()) /** - * A unique identifier used to link different project logs events together as part of a full - * trace. See the [tracing guide](https://www.braintrust.dev/docs/guides/tracing) for full - * details on tracing + * Sets [Builder.spanAttributes] to an arbitrary JSON value. + * + * You should usually call [Builder.spanAttributes] with a well-typed [SpanAttributes] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("span_id") - @ExcludeMissing - fun spanId(spanId: JsonField) = apply { this.spanId = spanId } + fun spanAttributes(spanAttributes: JsonField) = apply { + this.spanAttributes = spanAttributes + } /** * An array of the parent `span_ids` of this project logs event. This should be empty for * the root span of a trace, and should most often contain just one parent element for * subspans */ - fun spanParents(spanParents: List) = spanParents(JsonField.of(spanParents)) + fun spanParents(spanParents: List?) = spanParents(JsonField.ofNullable(spanParents)) + + /** Alias for calling [Builder.spanParents] with `spanParents.orElse(null)`. */ + fun spanParents(spanParents: Optional>) = spanParents(spanParents.getOrNull()) /** - * An array of the parent `span_ids` of this project logs event. This should be empty for - * the root span of a trace, and should most often contain just one parent element for - * subspans + * Sets [Builder.spanParents] to an arbitrary JSON value. + * + * You should usually call [Builder.spanParents] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("span_parents") - @ExcludeMissing fun spanParents(spanParents: JsonField>) = apply { - this.spanParents = spanParents + this.spanParents = spanParents.map { it.toMutableList() } } - /** The `span_id` of the root of the trace this project logs event belongs to */ - fun rootSpanId(rootSpanId: String) = rootSpanId(JsonField.of(rootSpanId)) + /** + * Adds a single [String] to [spanParents]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanParent(spanParent: String) = apply { + spanParents = + (spanParents ?: JsonField.of(mutableListOf())).also { + checkKnown("spanParents", it).add(spanParent) + } + } - /** The `span_id` of the root of the trace this project logs event belongs to */ - @JsonProperty("root_span_id") - @ExcludeMissing - fun rootSpanId(rootSpanId: JsonField) = apply { this.rootSpanId = rootSpanId } + /** A list of tags to log */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) - /** Human-identifying attributes of the span, such as name, type, etc. */ - fun spanAttributes(spanAttributes: SpanAttributes) = - spanAttributes(JsonField.of(spanAttributes)) + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonProperty("span_attributes") - @ExcludeMissing - fun spanAttributes(spanAttributes: JsonField) = apply { - this.spanAttributes = spanAttributes + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ProjectLogsEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .created() + * .logId() + * .orgId() + * .projectId() + * .rootSpanId() + * .spanId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectLogsEvent = ProjectLogsEvent( - id, - _xactId, - created, - orgId, - projectId, - logId, - input, - output, - expected, + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("created", created), + checkRequired("logId", logId), + checkRequired("orgId", orgId), + checkRequired("projectId", projectId), + checkRequired("rootSpanId", rootSpanId), + checkRequired("spanId", spanId), + context, error, - scores, + expected, + input, + isRoot, metadata, - tags.map { it.toUnmodifiable() }, metrics, - context, - spanId, - spanParents.map { it.toUnmodifiable() }, - rootSpanId, + origin, + output, + scores, spanAttributes, - additionalProperties.toUnmodifiable(), + (spanParents ?: JsonMissing.of()).map { it.toImmutable() }, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - class LogId - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** A literal 'g' which identifies the log as a project log */ + class LogId @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogId && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val G = LogId(JsonField.of("g")) + @JvmField val G = of("g") @JvmStatic fun of(value: String) = LogId(JsonField.of(value)) } + /** An enum containing [LogId]'s known values. */ enum class Known { - G, + G } + /** + * An enum containing [LogId]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [LogId] 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 { G, + /** An enum member indicating that [LogId] 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) { G -> Value.G 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { G -> Known.G else -> throw BraintrustInvalidDataException("Unknown LogId: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is LogId && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } /** @@ -733,160 +976,235 @@ private constructor( * essentially the textual counterpart to `metrics`. Use the `caller_*` attributes to track the * location in code which produced the project logs event */ - @JsonDeserialize(builder = Context.Builder::class) @NoAutoDetect class Context + @JsonCreator private constructor( - private val callerFunctionname: JsonField, - private val callerFilename: JsonField, - private val callerLineno: JsonField, - private val additionalProperties: Map, + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonField = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonField = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * Name of the file in code where the project logs event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callerFilename(): Optional = + Optional.ofNullable(callerFilename.getNullable("caller_filename")) - /** The function in code which created the project logs event */ + /** + * The function in code which created the project logs event + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun callerFunctionname(): Optional = Optional.ofNullable(callerFunctionname.getNullable("caller_functionname")) - /** Name of the file in code where the project logs event was created */ - fun callerFilename(): Optional = - Optional.ofNullable(callerFilename.getNullable("caller_filename")) - - /** Line of code where the project logs event was created */ + /** + * Line of code where the project logs event was created + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun callerLineno(): Optional = Optional.ofNullable(callerLineno.getNullable("caller_lineno")) - /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") + /** + * Returns the raw JSON value of [callerFilename]. + * + * Unlike [callerFilename], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_filename") @ExcludeMissing - fun _callerFunctionname() = callerFunctionname + fun _callerFilename(): JsonField = callerFilename - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") @ExcludeMissing fun _callerFilename() = callerFilename + /** + * Returns the raw JSON value of [callerFunctionname]. + * + * Unlike [callerFunctionname], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonField = callerFunctionname - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno() = callerLineno + /** + * Returns the raw JSON value of [callerLineno]. + * + * Unlike [callerLineno], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("caller_lineno") + @ExcludeMissing + fun _callerLineno(): JsonField = callerLineno @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Context = apply { - if (!validated) { - callerFunctionname() - callerFilename() - callerLineno() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Context = apply { + if (validated) { + return@apply } - return other is Context && - this.callerFunctionname == other.callerFunctionname && - this.callerFilename == other.callerFilename && - this.callerLineno == other.callerLineno && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - callerFunctionname, - callerFilename, - callerLineno, - additionalProperties, - ) - } - return hashCode + callerFilename() + callerFunctionname() + callerLineno() + validated = true } - override fun toString() = - "Context{callerFunctionname=$callerFunctionname, callerFilename=$callerFilename, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Context]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Context]. */ + class Builder internal constructor() { - private var callerFunctionname: JsonField = JsonMissing.of() private var callerFilename: JsonField = JsonMissing.of() + private var callerFunctionname: JsonField = JsonMissing.of() private var callerLineno: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(context: Context) = apply { - this.callerFunctionname = context.callerFunctionname - this.callerFilename = context.callerFilename - this.callerLineno = context.callerLineno - additionalProperties(context.additionalProperties) + callerFilename = context.callerFilename + callerFunctionname = context.callerFunctionname + callerLineno = context.callerLineno + additionalProperties = context.additionalProperties.toMutableMap() } - /** The function in code which created the project logs event */ - fun callerFunctionname(callerFunctionname: String) = - callerFunctionname(JsonField.of(callerFunctionname)) + /** Name of the file in code where the project logs event was created */ + fun callerFilename(callerFilename: String?) = + callerFilename(JsonField.ofNullable(callerFilename)) + + /** Alias for calling [Builder.callerFilename] with `callerFilename.orElse(null)`. */ + fun callerFilename(callerFilename: Optional) = + callerFilename(callerFilename.getOrNull()) + + /** + * Sets [Builder.callerFilename] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFilename] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callerFilename(callerFilename: JsonField) = apply { + this.callerFilename = callerFilename + } /** The function in code which created the project logs event */ - @JsonProperty("caller_functionname") - @ExcludeMissing + fun callerFunctionname(callerFunctionname: String?) = + callerFunctionname(JsonField.ofNullable(callerFunctionname)) + + /** + * Alias for calling [Builder.callerFunctionname] with + * `callerFunctionname.orElse(null)`. + */ + fun callerFunctionname(callerFunctionname: Optional) = + callerFunctionname(callerFunctionname.getOrNull()) + + /** + * Sets [Builder.callerFunctionname] to an arbitrary JSON value. + * + * You should usually call [Builder.callerFunctionname] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun callerFunctionname(callerFunctionname: JsonField) = apply { this.callerFunctionname = callerFunctionname } - /** Name of the file in code where the project logs event was created */ - fun callerFilename(callerFilename: String) = - callerFilename(JsonField.of(callerFilename)) + /** Line of code where the project logs event was created */ + fun callerLineno(callerLineno: Long?) = callerLineno(JsonField.ofNullable(callerLineno)) - /** Name of the file in code where the project logs event was created */ - @JsonProperty("caller_filename") - @ExcludeMissing - fun callerFilename(callerFilename: JsonField) = apply { - this.callerFilename = callerFilename - } + /** + * Alias for [Builder.callerLineno]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun callerLineno(callerLineno: Long) = callerLineno(callerLineno as Long?) - /** Line of code where the project logs event was created */ - fun callerLineno(callerLineno: Long) = callerLineno(JsonField.of(callerLineno)) + /** Alias for calling [Builder.callerLineno] with `callerLineno.orElse(null)`. */ + fun callerLineno(callerLineno: Optional) = callerLineno(callerLineno.getOrNull()) - /** Line of code where the project logs event was created */ - @JsonProperty("caller_lineno") - @ExcludeMissing + /** + * Sets [Builder.callerLineno] to an arbitrary JSON value. + * + * You should usually call [Builder.callerLineno] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun callerLineno(callerLineno: JsonField) = apply { this.callerLineno = callerLineno } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Context]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): Context = Context( - callerFunctionname, callerFilename, + callerFunctionname, callerLineno, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Context && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Context{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, additionalProperties=$additionalProperties}" } /** @@ -896,76 +1214,125 @@ private constructor( * slice/dice later. The values in `metadata` can be any JSON-serializable type, but its keys * must be strings */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonProperty("model") + @ExcludeMissing + private val model: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * The model used for this example + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) - private var hashCode: Int = 0 + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + model() + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { + private var model: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + model = metadata.model + additionalProperties = metadata.additionalProperties.toMutableMap() } + /** The model used for this example */ + fun model(model: String?) = model(JsonField.ofNullable(model)) + + /** Alias for calling [Builder.model] with `model.orElse(null)`. */ + fun model(model: Optional) = model(model.getOrNull()) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(model, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && model == other.model && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metadata{model=$model, additionalProperties=$additionalProperties}" } /** @@ -973,246 +1340,387 @@ private constructor( * project logs event. Use "start" and "end" to track the time span over which the project logs * event was produced */ - @JsonDeserialize(builder = Metrics.Builder::class) @NoAutoDetect class Metrics + @JsonCreator private constructor( - private val start: JsonField, - private val end: JsonField, - private val promptTokens: JsonField, - private val completionTokens: JsonField, - private val tokens: JsonField, - private val additionalProperties: Map, + @JsonProperty("caller_filename") + @ExcludeMissing + private val callerFilename: JsonValue = JsonMissing.of(), + @JsonProperty("caller_functionname") + @ExcludeMissing + private val callerFunctionname: JsonValue = JsonMissing.of(), + @JsonProperty("caller_lineno") + @ExcludeMissing + private val callerLineno: JsonValue = JsonMissing.of(), + @JsonProperty("completion_tokens") + @ExcludeMissing + private val completionTokens: JsonField = JsonMissing.of(), + @JsonProperty("end") @ExcludeMissing private val end: JsonField = JsonMissing.of(), + @JsonProperty("prompt_tokens") + @ExcludeMissing + private val promptTokens: JsonField = JsonMissing.of(), + @JsonProperty("start") + @ExcludeMissing + private val start: JsonField = JsonMissing.of(), + @JsonProperty("tokens") + @ExcludeMissing + private val tokens: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** This metric is deprecated */ + @JsonProperty("caller_filename") + @ExcludeMissing + fun _callerFilename(): JsonValue = callerFilename + + /** This metric is deprecated */ + @JsonProperty("caller_functionname") + @ExcludeMissing + fun _callerFunctionname(): JsonValue = callerFunctionname - private var hashCode: Int = 0 + /** This metric is deprecated */ + @JsonProperty("caller_lineno") @ExcludeMissing fun _callerLineno(): JsonValue = callerLineno /** - * A unix timestamp recording when the section of code which produced the project logs event - * started + * The number of tokens in the completion generated by the model (only set if this is an LLM + * span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun start(): Optional = Optional.ofNullable(start.getNullable("start")) + fun completionTokens(): Optional = + Optional.ofNullable(completionTokens.getNullable("completion_tokens")) /** * A unix timestamp recording when the section of code which produced the project logs event * finished + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ fun end(): Optional = Optional.ofNullable(end.getNullable("end")) /** * The number of tokens in the prompt used to generate the project logs event (only set if * this is an LLM span) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ fun promptTokens(): Optional = Optional.ofNullable(promptTokens.getNullable("prompt_tokens")) /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) + * A unix timestamp recording when the section of code which produced the project logs event + * started + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun completionTokens(): Optional = - Optional.ofNullable(completionTokens.getNullable("completion_tokens")) + fun start(): Optional = Optional.ofNullable(start.getNullable("start")) - /** The total number of tokens in the input and output of the project logs event. */ + /** + * The total number of tokens in the input and output of the project logs event. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun tokens(): Optional = Optional.ofNullable(tokens.getNullable("tokens")) /** - * A unix timestamp recording when the section of code which produced the project logs event - * started + * Returns the raw JSON value of [completionTokens]. + * + * Unlike [completionTokens], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("start") @ExcludeMissing fun _start() = start + @JsonProperty("completion_tokens") + @ExcludeMissing + fun _completionTokens(): JsonField = completionTokens /** - * A unix timestamp recording when the section of code which produced the project logs event - * finished + * Returns the raw JSON value of [end]. + * + * Unlike [end], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("end") @ExcludeMissing fun _end() = end + @JsonProperty("end") @ExcludeMissing fun _end(): JsonField = end /** - * The number of tokens in the prompt used to generate the project logs event (only set if - * this is an LLM span) + * Returns the raw JSON value of [promptTokens]. + * + * Unlike [promptTokens], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("prompt_tokens") @ExcludeMissing fun _promptTokens() = promptTokens + @JsonProperty("prompt_tokens") + @ExcludeMissing + fun _promptTokens(): JsonField = promptTokens /** - * The number of tokens in the completion generated by the model (only set if this is an LLM - * span) + * Returns the raw JSON value of [start]. + * + * Unlike [start], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun _completionTokens() = completionTokens + @JsonProperty("start") @ExcludeMissing fun _start(): JsonField = start - /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") @ExcludeMissing fun _tokens() = tokens + /** + * Returns the raw JSON value of [tokens]. + * + * Unlike [tokens], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tokens") @ExcludeMissing fun _tokens(): JsonField = tokens @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metrics = apply { - if (!validated) { - start() - end() - promptTokens() - completionTokens() - tokens() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metrics = apply { + if (validated) { + return@apply } - return other is Metrics && - this.start == other.start && - this.end == other.end && - this.promptTokens == other.promptTokens && - this.completionTokens == other.completionTokens && - this.tokens == other.tokens && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - start, - end, - promptTokens, - completionTokens, - tokens, - additionalProperties, - ) - } - return hashCode + completionTokens() + end() + promptTokens() + start() + tokens() + validated = true } - override fun toString() = - "Metrics{start=$start, end=$end, promptTokens=$promptTokens, completionTokens=$completionTokens, tokens=$tokens, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metrics]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metrics]. */ + class Builder internal constructor() { - private var start: JsonField = JsonMissing.of() + private var callerFilename: JsonValue = JsonMissing.of() + private var callerFunctionname: JsonValue = JsonMissing.of() + private var callerLineno: JsonValue = JsonMissing.of() + private var completionTokens: JsonField = JsonMissing.of() private var end: JsonField = JsonMissing.of() private var promptTokens: JsonField = JsonMissing.of() - private var completionTokens: JsonField = JsonMissing.of() + private var start: JsonField = JsonMissing.of() private var tokens: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metrics: Metrics) = apply { - this.start = metrics.start - this.end = metrics.end - this.promptTokens = metrics.promptTokens - this.completionTokens = metrics.completionTokens - this.tokens = metrics.tokens - additionalProperties(metrics.additionalProperties) + callerFilename = metrics.callerFilename + callerFunctionname = metrics.callerFunctionname + callerLineno = metrics.callerLineno + completionTokens = metrics.completionTokens + end = metrics.end + promptTokens = metrics.promptTokens + start = metrics.start + tokens = metrics.tokens + additionalProperties = metrics.additionalProperties.toMutableMap() + } + + /** This metric is deprecated */ + fun callerFilename(callerFilename: JsonValue) = apply { + this.callerFilename = callerFilename } + /** This metric is deprecated */ + fun callerFunctionname(callerFunctionname: JsonValue) = apply { + this.callerFunctionname = callerFunctionname + } + + /** This metric is deprecated */ + fun callerLineno(callerLineno: JsonValue) = apply { this.callerLineno = callerLineno } + /** - * A unix timestamp recording when the section of code which produced the project logs - * event started + * The number of tokens in the completion generated by the model (only set if this is an + * LLM span) */ - fun start(start: Double) = start(JsonField.of(start)) + fun completionTokens(completionTokens: Long?) = + completionTokens(JsonField.ofNullable(completionTokens)) /** - * A unix timestamp recording when the section of code which produced the project logs - * event started + * Alias for [Builder.completionTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("start") - @ExcludeMissing - fun start(start: JsonField) = apply { this.start = start } + fun completionTokens(completionTokens: Long) = + completionTokens(completionTokens as Long?) /** - * A unix timestamp recording when the section of code which produced the project logs - * event finished + * Alias for calling [Builder.completionTokens] with `completionTokens.orElse(null)`. + */ + fun completionTokens(completionTokens: Optional) = + completionTokens(completionTokens.getOrNull()) + + /** + * Sets [Builder.completionTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.completionTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun end(end: Double) = end(JsonField.of(end)) + fun completionTokens(completionTokens: JsonField) = apply { + this.completionTokens = completionTokens + } /** * A unix timestamp recording when the section of code which produced the project logs * event finished */ - @JsonProperty("end") - @ExcludeMissing + fun end(end: Double?) = end(JsonField.ofNullable(end)) + + /** + * Alias for [Builder.end]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun end(end: Double) = end(end as Double?) + + /** Alias for calling [Builder.end] with `end.orElse(null)`. */ + fun end(end: Optional) = end(end.getOrNull()) + + /** + * Sets [Builder.end] to an arbitrary JSON value. + * + * You should usually call [Builder.end] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun end(end: JsonField) = apply { this.end = end } /** * The number of tokens in the prompt used to generate the project logs event (only set * if this is an LLM span) */ - fun promptTokens(promptTokens: Long) = promptTokens(JsonField.of(promptTokens)) + fun promptTokens(promptTokens: Long?) = promptTokens(JsonField.ofNullable(promptTokens)) /** - * The number of tokens in the prompt used to generate the project logs event (only set - * if this is an LLM span) + * Alias for [Builder.promptTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun promptTokens(promptTokens: Long) = promptTokens(promptTokens as Long?) + + /** Alias for calling [Builder.promptTokens] with `promptTokens.orElse(null)`. */ + fun promptTokens(promptTokens: Optional) = promptTokens(promptTokens.getOrNull()) + + /** + * Sets [Builder.promptTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.promptTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("prompt_tokens") - @ExcludeMissing fun promptTokens(promptTokens: JsonField) = apply { this.promptTokens = promptTokens } /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) + * A unix timestamp recording when the section of code which produced the project logs + * event started */ - fun completionTokens(completionTokens: Long) = - completionTokens(JsonField.of(completionTokens)) + fun start(start: Double?) = start(JsonField.ofNullable(start)) /** - * The number of tokens in the completion generated by the model (only set if this is an - * LLM span) + * Alias for [Builder.start]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - @JsonProperty("completion_tokens") - @ExcludeMissing - fun completionTokens(completionTokens: JsonField) = apply { - this.completionTokens = completionTokens - } + fun start(start: Double) = start(start as Double?) - /** The total number of tokens in the input and output of the project logs event. */ - fun tokens(tokens: Long) = tokens(JsonField.of(tokens)) + /** Alias for calling [Builder.start] with `start.orElse(null)`. */ + fun start(start: Optional) = start(start.getOrNull()) + + /** + * Sets [Builder.start] to an arbitrary JSON value. + * + * You should usually call [Builder.start] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun start(start: JsonField) = apply { this.start = start } /** The total number of tokens in the input and output of the project logs event. */ - @JsonProperty("tokens") - @ExcludeMissing + fun tokens(tokens: Long?) = tokens(JsonField.ofNullable(tokens)) + + /** + * Alias for [Builder.tokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun tokens(tokens: Long) = tokens(tokens as Long?) + + /** Alias for calling [Builder.tokens] with `tokens.orElse(null)`. */ + fun tokens(tokens: Optional) = tokens(tokens.getOrNull()) + + /** + * Sets [Builder.tokens] to an arbitrary JSON value. + * + * You should usually call [Builder.tokens] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun tokens(tokens: JsonField) = apply { this.tokens = tokens } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Metrics]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): Metrics = Metrics( - start, + callerFilename, + callerFunctionname, + callerLineno, + completionTokens, end, promptTokens, - completionTokens, + start, tokens, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metrics && callerFilename == other.callerFilename && callerFunctionname == other.callerFunctionname && callerLineno == other.callerLineno && completionTokens == other.completionTokens && end == other.end && promptTokens == other.promptTokens && start == other.start && tokens == other.tokens && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(callerFilename, callerFunctionname, callerLineno, completionTokens, end, promptTokens, start, tokens, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Metrics{callerFilename=$callerFilename, callerFunctionname=$callerFunctionname, callerLineno=$callerLineno, completionTokens=$completionTokens, end=$end, promptTokens=$promptTokens, start=$start, tokens=$tokens, additionalProperties=$additionalProperties}" } /** @@ -1224,279 +1732,104 @@ private constructor( * whether the summarization was covering similar concepts or not. You can use these scores to * help you sort, filter, and compare logs. */ - @JsonDeserialize(builder = Scores.Builder::class) @NoAutoDetect class Scores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Scores = apply { + if (validated) { + return@apply } - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Scores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Scores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Scores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) + additionalProperties = scores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) - } - } - - /** Human-identifying attributes of the span, such as name, type, etc. */ - @JsonDeserialize(builder = SpanAttributes.Builder::class) - @NoAutoDetect - class SpanAttributes - private constructor( - private val name: JsonField, - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the span, for display purposes only */ - fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - - /** Type of the span, for display purposes only */ - fun type(): Optional = Optional.ofNullable(type.getNullable("type")) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - /** Name of the span, for display purposes only */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Type of the span, for display purposes only */ - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): SpanAttributes = apply { - if (!validated) { - name() - type() - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is SpanAttributes && - this.name == other.name && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - type, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { - - private var name: JsonField = JsonMissing.of() - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(spanAttributes: SpanAttributes) = apply { - this.name = spanAttributes.name - this.type = spanAttributes.type - additionalProperties(spanAttributes.additionalProperties) - } - - /** Name of the span, for display purposes only */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the span, for display purposes only */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Type of the span, for display purposes only */ - fun type(type: Type) = type(JsonField.of(type)) - - /** Type of the span, for display purposes only */ - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + override fun hashCode(): Int = hashCode - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun toString() = "Scores{additionalProperties=$additionalProperties}" + } - fun build(): SpanAttributes = - SpanAttributes( - name, - type, - additionalProperties.toUnmodifiable(), - ) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val LLM = Type(JsonField.of("llm")) - - @JvmField val SCORE = Type(JsonField.of("score")) - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmField val EVAL = Type(JsonField.of("eval")) - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmField val TOOL = Type(JsonField.of("tool")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - } - - enum class Value { - LLM, - SCORE, - FUNCTION, - EVAL, - TASK, - TOOL, - _UNKNOWN, - } + return /* spotless:off */ other is ProjectLogsEvent && id == other.id && _xactId == other._xactId && created == other.created && logId == other.logId && orgId == other.orgId && projectId == other.projectId && rootSpanId == other.rootSpanId && spanId == other.spanId && context == other.context && error == other.error && expected == other.expected && input == other.input && isRoot == other.isRoot && metadata == other.metadata && metrics == other.metrics && origin == other.origin && output == other.output && scores == other.scores && spanAttributes == other.spanAttributes && spanParents == other.spanParents && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - LLM -> Value.LLM - SCORE -> Value.SCORE - FUNCTION -> Value.FUNCTION - EVAL -> Value.EVAL - TASK -> Value.TASK - TOOL -> Value.TOOL - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, created, logId, orgId, projectId, rootSpanId, spanId, context, error, expected, input, isRoot, metadata, metrics, origin, output, scores, spanAttributes, spanParents, tags, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - LLM -> Known.LLM - SCORE -> Known.SCORE - FUNCTION -> Known.FUNCTION - EVAL -> Known.EVAL - TASK -> Known.TASK - TOOL -> Known.TOOL - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "ProjectLogsEvent{id=$id, _xactId=$_xactId, created=$created, logId=$logId, orgId=$orgId, projectId=$projectId, rootSpanId=$rootSpanId, spanId=$spanId, context=$context, error=$error, expected=$expected, input=$input, isRoot=$isRoot, metadata=$metadata, metrics=$metrics, origin=$origin, output=$output, scores=$scores, spanAttributes=$spanAttributes, spanParents=$spanParents, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectRetrieveParams.kt index 37a0e287..36e479aa 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a project object by its id */ class ProjectRetrieveParams -constructor( +private constructor( private val projectId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectRetrieveParams && - this.projectId == other.projectId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - projectId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectRetrieveParams{projectId=$projectId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectRetrieveParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectRetrieveParams: ProjectRetrieveParams) = apply { - this.projectId = projectRetrieveParams.projectId - additionalQueryParams(projectRetrieveParams.additionalQueryParams) - additionalHeaders(projectRetrieveParams.additionalHeaders) + projectId = projectRetrieveParams.projectId + additionalHeaders = projectRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = projectRetrieveParams.additionalQueryParams.toBuilder() } /** Project id */ fun projectId(projectId: String) = apply { this.projectId = projectId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectRetrieveParams = ProjectRetrieveParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("projectId", projectId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectRetrieveParams && projectId == other.projectId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectRetrieveParams{projectId=$projectId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScore.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScore.kt index 41a70ed4..023cbd6f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScore.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScore.kt @@ -9,11 +9,14 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec @@ -25,353 +28,524 @@ import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** A project score is a user-configured score, which can be manually-labeled through the UI */ -@JsonDeserialize(builder = ProjectScore.Builder::class) @NoAutoDetect class ProjectScore +@JsonCreator private constructor( - private val id: JsonField, - private val projectId: JsonField, - private val userId: JsonField, - private val created: JsonField, - private val name: JsonField, - private val description: JsonField, - private val scoreType: JsonField, - private val categories: JsonField, - private val config: JsonField, - private val position: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("score_type") + @ExcludeMissing + private val scoreType: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("categories") + @ExcludeMissing + private val categories: JsonField = JsonMissing.of(), + @JsonProperty("config") + @ExcludeMissing + private val config: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("position") + @ExcludeMissing + private val position: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the project score */ + /** + * Unique identifier for the project score + * + * @throws BraintrustInvalidDataException 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") - /** Unique identifier for the project that the project score belongs under */ - fun projectId(): String = projectId.getRequired("project_id") - - fun userId(): String = userId.getRequired("user_id") - - /** Date of project score creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - - /** Name of the project score */ + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the project score */ - fun description(): Optional = - Optional.ofNullable(description.getNullable("description")) + /** + * Unique identifier for the project that the project score belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** The type of the configured score */ + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException 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 scoreType(): ProjectScoreType = scoreType.getRequired("score_type") + /** + * @throws BraintrustInvalidDataException 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 userId(): String = userId.getRequired("user_id") + + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun categories(): Optional = Optional.ofNullable(categories.getNullable("categories")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun config(): Optional = Optional.ofNullable(config.getNullable("config")) - /** An optional LexoRank-based string that sets the sort position for the score in the UI */ - fun position(): Optional = Optional.ofNullable(position.getNullable("position")) - - /** Unique identifier for the project score */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId - - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId - - /** Date of project score creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Name of the project score */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Textual description of the project score */ - @JsonProperty("description") @ExcludeMissing fun _description() = description - - /** The type of the configured score */ - @JsonProperty("score_type") @ExcludeMissing fun _scoreType() = scoreType + /** + * Date of project score creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - @JsonProperty("categories") @ExcludeMissing fun _categories() = categories + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - @JsonProperty("config") @ExcludeMissing fun _config() = config + /** + * An optional LexoRank-based string that sets the sort position for the score in the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun position(): Optional = Optional.ofNullable(position.getNullable("position")) - /** An optional LexoRank-based string that sets the sort position for the score in the UI */ - @JsonProperty("position") @ExcludeMissing fun _position() = position + /** + * 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 [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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("score_type") + @ExcludeMissing + fun _scoreType(): JsonField = scoreType + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("config") @ExcludeMissing fun _config(): JsonField = config + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * 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 [position]. + * + * Unlike [position], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("position") @ExcludeMissing fun _position(): JsonField = position @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectScore = apply { - if (!validated) { - id() - projectId() - userId() - created() - name() - description() - scoreType() - categories() - config().map { it.validate() } - position() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectScore = apply { + if (validated) { + return@apply } - return other is ProjectScore && - this.id == other.id && - this.projectId == other.projectId && - this.userId == other.userId && - this.created == other.created && - this.name == other.name && - this.description == other.description && - this.scoreType == other.scoreType && - this.categories == other.categories && - this.config == other.config && - this.position == other.position && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - projectId, - userId, - created, - name, - description, - scoreType, - categories, - config, - position, - additionalProperties, - ) - } - return hashCode + id() + name() + projectId() + scoreType() + userId() + categories().ifPresent { it.validate() } + config().ifPresent { it.validate() } + created() + description() + position() + validated = true } - override fun toString() = - "ProjectScore{id=$id, projectId=$projectId, userId=$userId, created=$created, name=$name, description=$description, scoreType=$scoreType, categories=$categories, config=$config, position=$position, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScore]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .scoreType() + * .userId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectScore]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() - private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() - private var scoreType: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var scoreType: JsonField? = null + private var userId: JsonField? = null private var categories: JsonField = JsonMissing.of() private var config: JsonField = JsonMissing.of() + private var created: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var position: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectScore: ProjectScore) = apply { - this.id = projectScore.id - this.projectId = projectScore.projectId - this.userId = projectScore.userId - this.created = projectScore.created - this.name = projectScore.name - this.description = projectScore.description - this.scoreType = projectScore.scoreType - this.categories = projectScore.categories - this.config = projectScore.config - this.position = projectScore.position - additionalProperties(projectScore.additionalProperties) + id = projectScore.id + name = projectScore.name + projectId = projectScore.projectId + scoreType = projectScore.scoreType + userId = projectScore.userId + categories = projectScore.categories + config = projectScore.config + created = projectScore.created + description = projectScore.description + position = projectScore.position + additionalProperties = projectScore.additionalProperties.toMutableMap() } /** Unique identifier for the project score */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the project score */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Unique identifier for the project that the project score belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - - /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - - fun userId(userId: String) = userId(JsonField.of(userId)) - - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } - - /** Date of project score creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** Date of project score creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** + * 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 } /** Name of the project score */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the project score */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } - /** Textual description of the project score */ - fun description(description: String) = description(JsonField.of(description)) + /** Unique identifier for the project that the project score belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Textual description of the project score */ - @JsonProperty("description") - @ExcludeMissing - fun description(description: JsonField) = apply { this.description = description } + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** The type of the configured score */ fun scoreType(scoreType: ProjectScoreType) = scoreType(JsonField.of(scoreType)) - /** The type of the configured score */ - @JsonProperty("score_type") - @ExcludeMissing + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun scoreType(scoreType: JsonField) = apply { this.scoreType = scoreType } - fun categories(categories: Categories) = categories(JsonField.of(categories)) + fun userId(userId: String) = userId(JsonField.of(userId)) - @JsonProperty("categories") - @ExcludeMissing + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + + /** For categorical-type project scores, the list of all categories */ + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun categories(categories: JsonField) = apply { this.categories = categories } - fun config(config: ProjectScoreConfig) = config(JsonField.of(config)) + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = + categories(Categories.ofCategorical(categorical)) + + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = categories(Categories.ofWeighted(weighted)) - @JsonProperty("config") - @ExcludeMissing + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = categories(Categories.ofMinimum(minimum)) + + fun config(config: ProjectScoreConfig?) = config(JsonField.ofNullable(config)) + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun config(config: JsonField) = apply { this.config = config } - /** An optional LexoRank-based string that sets the sort position for the score in the UI */ - fun position(position: String) = position(JsonField.of(position)) + /** Date of project score creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** Textual description of the project score */ + 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 } /** An optional LexoRank-based string that sets the sort position for the score in the UI */ - @JsonProperty("position") - @ExcludeMissing + fun position(position: String?) = position(JsonField.ofNullable(position)) + + /** Alias for calling [Builder.position] with `position.orElse(null)`. */ + fun position(position: Optional) = position(position.getOrNull()) + + /** + * Sets [Builder.position] to an arbitrary JSON value. + * + * You should usually call [Builder.position] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun position(position: JsonField) = apply { this.position = position } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ProjectScore]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .scoreType() + * .userId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScore = ProjectScore( - id, - projectId, - userId, - created, - name, - description, - scoreType, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("scoreType", scoreType), + checkRequired("userId", userId), categories, config, + created, + description, position, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + /** For categorical-type project scores, the list of all categories */ @JsonDeserialize(using = Categories.Deserializer::class) @JsonSerialize(using = Categories.Serializer::class) class Categories private constructor( - private val projectScoreCategories: List? = null, + private val categorical: List? = null, private val weighted: Weighted? = null, - private val strings: List? = null, - private val nullableVariant: NullableVariant? = null, + private val minimum: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(): Optional> = - Optional.ofNullable(projectScoreCategories) + fun categorical(): Optional> = Optional.ofNullable(categorical) + /** For weighted-type project scores, the weights of each score */ fun weighted(): Optional = Optional.ofNullable(weighted) - /** For minimum-type project scores, the list of included scores */ - fun strings(): Optional> = Optional.ofNullable(strings) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) + /** For minimum-type project scores, the list of included scores */ + fun minimum(): Optional> = Optional.ofNullable(minimum) - fun isProjectScoreCategories(): Boolean = projectScoreCategories != null + fun isCategorical(): Boolean = categorical != null fun isWeighted(): Boolean = weighted != null - fun isStrings(): Boolean = strings != null - - fun isNullableVariant(): Boolean = nullableVariant != null + fun isMinimum(): Boolean = minimum != null - fun asProjectScoreCategories(): List = - projectScoreCategories.getOrThrow("projectScoreCategories") + /** For categorical-type project scores, the list of all categories */ + fun asCategorical(): List = categorical.getOrThrow("categorical") + /** For weighted-type project scores, the weights of each score */ fun asWeighted(): Weighted = weighted.getOrThrow("weighted") - fun asStrings(): List = strings.getOrThrow("strings") - - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") + /** For minimum-type project scores, the list of included scores */ + fun asMinimum(): List = minimum.getOrThrow("minimum") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - projectScoreCategories != null -> - visitor.visitProjectScoreCategories(projectScoreCategories) + categorical != null -> visitor.visitCategorical(categorical) weighted != null -> visitor.visitWeighted(weighted) - strings != null -> visitor.visitStrings(strings) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) + minimum != null -> visitor.visitMinimum(minimum) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Categories = apply { - if (!validated) { - if ( - projectScoreCategories == null && - weighted == null && - strings == null && - nullableVariant == null - ) { - throw BraintrustInvalidDataException("Unknown Categories: $_json") - } - projectScoreCategories?.forEach { it.validate() } - weighted?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitCategorical(categorical: List) { + categorical.forEach { it.validate() } + } + + override fun visitWeighted(weighted: Weighted) { + weighted.validate() + } + + override fun visitMinimum(minimum: List) {} + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -379,103 +553,97 @@ private constructor( return true } - return other is Categories && - this.projectScoreCategories == other.projectScoreCategories && - this.weighted == other.weighted && - this.strings == other.strings && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is Categories && categorical == other.categorical && weighted == other.weighted && minimum == other.minimum /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoreCategories, - weighted, - strings, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(categorical, weighted, minimum) /* spotless:on */ - override fun toString(): String { - return when { - projectScoreCategories != null -> - "Categories{projectScoreCategories=$projectScoreCategories}" + override fun toString(): String = + when { + categorical != null -> "Categories{categorical=$categorical}" weighted != null -> "Categories{weighted=$weighted}" - strings != null -> "Categories{strings=$strings}" - nullableVariant != null -> "Categories{nullableVariant=$nullableVariant}" + minimum != null -> "Categories{minimum=$minimum}" _json != null -> "Categories{_unknown=$_json}" else -> throw IllegalStateException("Invalid Categories") } - } companion object { + /** For categorical-type project scores, the list of all categories */ @JvmStatic - fun ofProjectScoreCategories(projectScoreCategories: List) = - Categories(projectScoreCategories = projectScoreCategories) + fun ofCategorical(categorical: List) = + Categories(categorical = categorical) + /** For weighted-type project scores, the weights of each score */ @JvmStatic fun ofWeighted(weighted: Weighted) = Categories(weighted = weighted) - @JvmStatic fun ofStrings(strings: List) = Categories(strings = strings) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - Categories(nullableVariant = nullableVariant) + /** For minimum-type project scores, the list of included scores */ + @JvmStatic fun ofMinimum(minimum: List) = Categories(minimum = minimum) } + /** + * An interface that defines how to map each variant of [Categories] to a value of type [T]. + */ interface Visitor { - fun visitProjectScoreCategories(projectScoreCategories: List): T + /** For categorical-type project scores, the list of all categories */ + fun visitCategorical(categorical: List): T + /** For weighted-type project scores, the weights of each score */ fun visitWeighted(weighted: Weighted): T - fun visitStrings(strings: List): T - - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** For minimum-type project scores, the list of included scores */ + fun visitMinimum(minimum: List): T + + /** + * Maps an unknown variant of [Categories] to a value of type [T]. + * + * An instance of [Categories] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Categories: $json") } } - class Deserializer : BaseDeserializer(Categories::class) { + internal class Deserializer : BaseDeserializer(Categories::class) { override fun ObjectCodec.deserialize(node: JsonNode): Categories { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef>()) { it.forEach { it.validate() } } ?.let { - return Categories(projectScoreCategories = it, _json = json) + return Categories(categorical = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Categories(weighted = it, _json = json) } tryDeserialize(node, jacksonTypeRef>())?.let { - return Categories(strings = it, _json = json) + return Categories(minimum = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Categories(nullableVariant = it, _json = json) - } return Categories(_json = json) } } - class Serializer : BaseSerializer(Categories::class) { + internal class Serializer : BaseSerializer(Categories::class) { override fun serialize( value: Categories, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.projectScoreCategories != null -> - generator.writeObject(value.projectScoreCategories) + value.categorical != null -> generator.writeObject(value.categorical) value.weighted != null -> generator.writeObject(value.weighted) - value.strings != null -> generator.writeObject(value.strings) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) + value.minimum != null -> generator.writeObject(value.minimum) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Categories") } @@ -483,68 +651,53 @@ private constructor( } /** For weighted-type project scores, the weights of each score */ - @JsonDeserialize(builder = Weighted.Builder::class) @NoAutoDetect class Weighted + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Weighted = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Weighted = apply { + if (validated) { + return@apply } - return other is Weighted && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Weighted]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Weighted]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(weighted: Weighted) = apply { - additionalProperties(weighted.additionalProperties) + additionalProperties = weighted.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -552,83 +705,54 @@ private constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Weighted = Weighted(additionalProperties.toUnmodifiable()) - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Weighted]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Weighted = Weighted(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Weighted && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - @JvmStatic fun builder() = Builder() - } + override fun hashCode(): Int = hashCode - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() + override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + } + } - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + return /* spotless:off */ other is ProjectScore && id == other.id && name == other.name && projectId == other.projectId && scoreType == other.scoreType && userId == other.userId && categories == other.categories && config == other.config && created == other.created && description == other.description && position == other.position && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, projectId, scoreType, userId, categories, config, created, description, position, additionalProperties) } + /* spotless:on */ - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = hashCode - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } - } - } + override fun toString() = + "ProjectScore{id=$id, name=$name, projectId=$projectId, scoreType=$scoreType, userId=$userId, categories=$categories, config=$config, created=$created, description=$description, position=$position, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCategory.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCategory.kt index e7c56679..b4504114 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCategory.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCategory.kt @@ -7,132 +7,178 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects /** For categorical-type project scores, defines a single category */ -@JsonDeserialize(builder = ProjectScoreCategory.Builder::class) @NoAutoDetect class ProjectScoreCategory +@JsonCreator private constructor( - private val name: JsonField, - private val value: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("value") @ExcludeMissing private val value: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Name of the category */ + /** + * Name of the category + * + * @throws BraintrustInvalidDataException 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") - /** Numerical value of the category. Must be between 0 and 1, inclusive */ + /** + * Numerical value of the category. Must be between 0 and 1, inclusive + * + * @throws BraintrustInvalidDataException 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 value(): Double = value.getRequired("value") - /** Name of the category */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 - /** Numerical value of the category. Must be between 0 and 1, inclusive */ - @JsonProperty("value") @ExcludeMissing fun _value() = value + /** + * Returns the raw JSON value of [value]. + * + * Unlike [value], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("value") @ExcludeMissing fun _value(): JsonField = value @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectScoreCategory = apply { - if (!validated) { - name() - value() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectScoreCategory = apply { + if (validated) { + return@apply } - return other is ProjectScoreCategory && - this.name == other.name && - this.value == other.value && - this.additionalProperties == other.additionalProperties + name() + value() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - value, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectScoreCategory{name=$name, value=$value, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreCategory]. + * + * The following fields are required: + * ```java + * .name() + * .value() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectScoreCategory]. */ + class Builder internal constructor() { - private var name: JsonField = JsonMissing.of() - private var value: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var value: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectScoreCategory: ProjectScoreCategory) = apply { - this.name = projectScoreCategory.name - this.value = projectScoreCategory.value - additionalProperties(projectScoreCategory.additionalProperties) + name = projectScoreCategory.name + value = projectScoreCategory.value + additionalProperties = projectScoreCategory.additionalProperties.toMutableMap() } /** Name of the category */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the category */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } /** Numerical value of the category. Must be between 0 and 1, inclusive */ fun value(value: Double) = value(JsonField.of(value)) - /** Numerical value of the category. Must be between 0 and 1, inclusive */ - @JsonProperty("value") - @ExcludeMissing + /** + * Sets [Builder.value] to an arbitrary JSON value. + * + * You should usually call [Builder.value] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun value(value: JsonField) = apply { this.value = value } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ProjectScoreCategory]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .value() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreCategory = ProjectScoreCategory( - name, - value, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("value", value), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectScoreCategory && name == other.name && value == other.value && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, value, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectScoreCategory{name=$name, value=$value, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreConfig.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreConfig.kt index af9b299e..4ec3a301 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreConfig.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreConfig.kt @@ -2,204 +2,213 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ProjectScoreConfig.Builder::class) @NoAutoDetect class ProjectScoreConfig +@JsonCreator private constructor( - private val multiSelect: JsonField, - private val destination: JsonField, - private val online: JsonField, - private val additionalProperties: Map, + @JsonProperty("destination") + @ExcludeMissing + private val destination: JsonField = JsonMissing.of(), + @JsonProperty("multi_select") + @ExcludeMissing + private val multiSelect: JsonField = JsonMissing.of(), + @JsonProperty("online") + @ExcludeMissing + private val online: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun destination(): Optional = + Optional.ofNullable(destination.getNullable("destination")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun multiSelect(): Optional = Optional.ofNullable(multiSelect.getNullable("multi_select")) - fun destination(): Optional = - Optional.ofNullable(destination.getNullable("destination")) - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun online(): Optional = Optional.ofNullable(online.getNullable("online")) - @JsonProperty("multi_select") @ExcludeMissing fun _multiSelect() = multiSelect - - @JsonProperty("destination") @ExcludeMissing fun _destination() = destination + /** + * Returns the raw JSON value of [destination]. + * + * Unlike [destination], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("destination") @ExcludeMissing fun _destination(): JsonField = destination + + /** + * Returns the raw JSON value of [multiSelect]. + * + * Unlike [multiSelect], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("multi_select") + @ExcludeMissing + fun _multiSelect(): JsonField = multiSelect - @JsonProperty("online") @ExcludeMissing fun _online() = online + /** + * Returns the raw JSON value of [online]. + * + * Unlike [online], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("online") @ExcludeMissing fun _online(): JsonField = online @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectScoreConfig = apply { - if (!validated) { - multiSelect() - destination() - online().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectScoreConfig = apply { + if (validated) { + return@apply } - return other is ProjectScoreConfig && - this.multiSelect == other.multiSelect && - this.destination == other.destination && - this.online == other.online && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - multiSelect, - destination, - online, - additionalProperties, - ) - } - return hashCode + destination() + multiSelect() + online().ifPresent { it.validate() } + validated = true } - override fun toString() = - "ProjectScoreConfig{multiSelect=$multiSelect, destination=$destination, online=$online, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ProjectScoreConfig]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectScoreConfig]. */ + class Builder internal constructor() { + private var destination: JsonField = JsonMissing.of() private var multiSelect: JsonField = JsonMissing.of() - private var destination: JsonField = JsonMissing.of() private var online: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectScoreConfig: ProjectScoreConfig) = apply { - this.multiSelect = projectScoreConfig.multiSelect - this.destination = projectScoreConfig.destination - this.online = projectScoreConfig.online - additionalProperties(projectScoreConfig.additionalProperties) + destination = projectScoreConfig.destination + multiSelect = projectScoreConfig.multiSelect + online = projectScoreConfig.online + additionalProperties = projectScoreConfig.additionalProperties.toMutableMap() } - fun multiSelect(multiSelect: Boolean) = multiSelect(JsonField.of(multiSelect)) - - @JsonProperty("multi_select") - @ExcludeMissing + fun destination(destination: String?) = destination(JsonField.ofNullable(destination)) + + /** Alias for calling [Builder.destination] with `destination.orElse(null)`. */ + fun destination(destination: Optional) = destination(destination.getOrNull()) + + /** + * Sets [Builder.destination] to an arbitrary JSON value. + * + * You should usually call [Builder.destination] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun destination(destination: JsonField) = apply { this.destination = destination } + + fun multiSelect(multiSelect: Boolean?) = multiSelect(JsonField.ofNullable(multiSelect)) + + /** + * Alias for [Builder.multiSelect]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun multiSelect(multiSelect: Boolean) = multiSelect(multiSelect as Boolean?) + + /** Alias for calling [Builder.multiSelect] with `multiSelect.orElse(null)`. */ + fun multiSelect(multiSelect: Optional) = multiSelect(multiSelect.getOrNull()) + + /** + * Sets [Builder.multiSelect] to an arbitrary JSON value. + * + * You should usually call [Builder.multiSelect] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun multiSelect(multiSelect: JsonField) = apply { this.multiSelect = multiSelect } - fun destination(destination: Destination) = destination(JsonField.of(destination)) - - @JsonProperty("destination") - @ExcludeMissing - fun destination(destination: JsonField) = apply { - this.destination = destination - } + fun online(online: OnlineScoreConfig?) = online(JsonField.ofNullable(online)) - fun online(online: OnlineScoreConfig) = online(JsonField.of(online)) + /** Alias for calling [Builder.online] with `online.orElse(null)`. */ + fun online(online: Optional) = online(online.getOrNull()) - @JsonProperty("online") - @ExcludeMissing + /** + * Sets [Builder.online] to an arbitrary JSON value. + * + * You should usually call [Builder.online] with a well-typed [OnlineScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun online(online: JsonField) = apply { this.online = online } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectScoreConfig = - ProjectScoreConfig( - multiSelect, - destination, - online, - additionalProperties.toUnmodifiable(), - ) - } - - class Destination - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Destination && this.value == other.value + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val EXPECTED = Destination(JsonField.of("expected")) - - @JvmStatic fun of(value: String) = Destination(JsonField.of(value)) - } + /** + * Returns an immutable instance of [ProjectScoreConfig]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ProjectScoreConfig = + ProjectScoreConfig(destination, multiSelect, online, additionalProperties.toImmutable()) + } - enum class Known { - EXPECTED, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - enum class Value { - EXPECTED, - _UNKNOWN, - } + return /* spotless:off */ other is ProjectScoreConfig && destination == other.destination && multiSelect == other.multiSelect && online == other.online && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - EXPECTED -> Value.EXPECTED - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(destination, multiSelect, online, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - EXPECTED -> Known.EXPECTED - else -> throw BraintrustInvalidDataException("Unknown Destination: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "ProjectScoreConfig{destination=$destination, multiSelect=$multiSelect, online=$online, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParams.kt index f2731c38..6b60c606 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParams.kt @@ -5,13 +5,21 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec @@ -22,441 +30,793 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new project_score. If there is an existing project_score in the project with the same + * name as the one specified in the request, will return the existing project_score unmodified + */ class ProjectScoreCreateParams -constructor( - private val name: String, - private val projectId: String, - private val scoreType: ProjectScoreType, - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun scoreType(): ProjectScoreType = scoreType - - fun categories(): Optional = Optional.ofNullable(categories) - - fun config(): Optional = Optional.ofNullable(config) - - fun description(): Optional = Optional.ofNullable(description) - - @JvmSynthetic - internal fun getBody(): ProjectScoreCreateBody { - return ProjectScoreCreateBody( - name, - projectId, - scoreType, - categories, - config, - description, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the project score belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException 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 scoreType(): ProjectScoreType = body.scoreType() + + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun categories(): Optional = body.categories() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun config(): Optional = body.config() + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _scoreType(): JsonField = body._scoreType() + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _categories(): JsonField = body._categories() + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _config(): JsonField = body._config() + + /** + * 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() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams /** A project score is a user-configured score, which can be manually-labeled through the UI */ - @JsonDeserialize(builder = ProjectScoreCreateBody.Builder::class) @NoAutoDetect - class ProjectScoreCreateBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val scoreType: ProjectScoreType?, - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("score_type") + @ExcludeMissing + private val scoreType: JsonField = JsonMissing.of(), + @JsonProperty("categories") + @ExcludeMissing + private val categories: JsonField = JsonMissing.of(), + @JsonProperty("config") + @ExcludeMissing + private val config: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project score */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** The type of the configured score */ - @JsonProperty("score_type") fun scoreType(): ProjectScoreType? = scoreType - - @JsonProperty("categories") fun categories(): Categories? = categories - - @JsonProperty("config") fun config(): ProjectScoreConfig? = config - - /** Textual description of the project score */ - @JsonProperty("description") fun description(): String? = description + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the project score belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException 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 scoreType(): ProjectScoreType = scoreType.getRequired("score_type") + + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun categories(): Optional = + Optional.ofNullable(categories.getNullable("categories")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun config(): Optional = + Optional.ofNullable(config.getNullable("config")) + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("score_type") + @ExcludeMissing + fun _scoreType(): JsonField = scoreType + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("config") + @ExcludeMissing + fun _config(): JsonField = config + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectScoreCreateBody && - this.name == other.name && - this.projectId == other.projectId && - this.scoreType == other.scoreType && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - scoreType, - categories, - config, - description, - additionalProperties, - ) - } - return hashCode + name() + projectId() + scoreType() + categories().ifPresent { it.validate() } + config().ifPresent { it.validate() } + description() + validated = true } - override fun toString() = - "ProjectScoreCreateBody{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalProperties=$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() + * .projectId() + * .scoreType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var scoreType: ProjectScoreType? = null - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var scoreType: JsonField? = null + private var categories: JsonField = JsonMissing.of() + private var config: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectScoreCreateBody: ProjectScoreCreateBody) = apply { - this.name = projectScoreCreateBody.name - this.projectId = projectScoreCreateBody.projectId - this.scoreType = projectScoreCreateBody.scoreType - this.categories = projectScoreCreateBody.categories - this.config = projectScoreCreateBody.config - this.description = projectScoreCreateBody.description - additionalProperties(projectScoreCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + scoreType = body.scoreType + categories = body.categories + config = body.config + description = body.description + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project score */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** The type of the configured score */ - @JsonProperty("score_type") - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType) = scoreType(JsonField.of(scoreType)) + + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun scoreType(scoreType: JsonField) = apply { + this.scoreType = scoreType + } - @JsonProperty("categories") - fun categories(categories: Categories) = apply { this.categories = categories } + /** For categorical-type project scores, the list of all categories */ + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { + this.categories = categories + } + + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = + categories(Categories.ofCategorical(categorical)) + + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = + categories(Categories.ofWeighted(weighted)) + + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = + categories(Categories.ofMinimum(minimum)) - @JsonProperty("config") - fun config(config: ProjectScoreConfig) = apply { this.config = config } + fun config(config: ProjectScoreConfig?) = config(JsonField.ofNullable(config)) + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { this.config = config } /** Textual description of the project score */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectScoreCreateBody = - ProjectScoreCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scoreType) { "`scoreType` is required but was not set" }, + 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() + * .projectId() + * .scoreType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("scoreType", scoreType), categories, config, description, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && scoreType == other.scoreType && categories == other.categories && config == other.config && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectScoreCreateParams && - this.name == other.name && - this.projectId == other.projectId && - this.scoreType == other.scoreType && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, scoreType, categories, config, description, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - scoreType, - categories, - config, - description, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectScoreCreateParams{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .scoreType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreCreateParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var projectId: String? = null - private var scoreType: ProjectScoreType? = null - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(projectScoreCreateParams: ProjectScoreCreateParams) = apply { - this.name = projectScoreCreateParams.name - this.projectId = projectScoreCreateParams.projectId - this.scoreType = projectScoreCreateParams.scoreType - this.categories = projectScoreCreateParams.categories - this.config = projectScoreCreateParams.config - this.description = projectScoreCreateParams.description - additionalQueryParams(projectScoreCreateParams.additionalQueryParams) - additionalHeaders(projectScoreCreateParams.additionalHeaders) - additionalBodyProperties(projectScoreCreateParams.additionalBodyProperties) + body = projectScoreCreateParams.body.toBuilder() + additionalHeaders = projectScoreCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreCreateParams.additionalQueryParams.toBuilder() } /** Name of the project score */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the project score belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** The type of the configured score */ - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType) = apply { body.scoreType(scoreType) } - /** For categorical-type project scores, the list of all categories */ - fun categories(categories: Categories) = apply { this.categories = categories } + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scoreType(scoreType: JsonField) = apply { body.scoreType(scoreType) } /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(projectScoreCategories: List) = apply { - this.categories = Categories.ofProjectScoreCategories(projectScoreCategories) + fun categories(categories: Categories?) = apply { body.categories(categories) } + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { body.categories(categories) } + + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = apply { + body.categoriesOfCategorical(categorical) } - /** For categorical-type project scores, the list of all categories */ - fun categories(weighted: Categories.Weighted) = apply { - this.categories = Categories.ofWeighted(weighted) + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = apply { body.categories(weighted) } + + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = apply { body.categoriesOfMinimum(minimum) } + + fun config(config: ProjectScoreConfig?) = apply { body.config(config) } + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { body.config(config) } + + /** Textual description of the project score */ + 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) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - /** For categorical-type project scores, the list of all categories */ - fun categories(strings: List) = apply { - this.categories = Categories.ofStrings(strings) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - /** For categorical-type project scores, the list of all categories */ - fun categories(nullableVariant: Categories.NullableVariant) = apply { - this.categories = Categories.ofNullableVariant(nullableVariant) + 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 config(config: ProjectScoreConfig) = apply { this.config = config } + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - /** Textual description of the project score */ - fun description(description: String) = apply { this.description = description } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectScoreCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .scoreType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreCreateParams = ProjectScoreCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scoreType) { "`scoreType` is required but was not set" }, - categories, - config, - description, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** For categorical-type project scores, the list of all categories */ @JsonDeserialize(using = Categories.Deserializer::class) @JsonSerialize(using = Categories.Serializer::class) class Categories private constructor( - private val projectScoreCategories: List? = null, + private val categorical: List? = null, private val weighted: Weighted? = null, - private val strings: List? = null, - private val nullableVariant: NullableVariant? = null, + private val minimum: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(): Optional> = - Optional.ofNullable(projectScoreCategories) + fun categorical(): Optional> = Optional.ofNullable(categorical) + /** For weighted-type project scores, the weights of each score */ fun weighted(): Optional = Optional.ofNullable(weighted) - /** For minimum-type project scores, the list of included scores */ - fun strings(): Optional> = Optional.ofNullable(strings) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) + /** For minimum-type project scores, the list of included scores */ + fun minimum(): Optional> = Optional.ofNullable(minimum) - fun isProjectScoreCategories(): Boolean = projectScoreCategories != null + fun isCategorical(): Boolean = categorical != null fun isWeighted(): Boolean = weighted != null - fun isStrings(): Boolean = strings != null - - fun isNullableVariant(): Boolean = nullableVariant != null + fun isMinimum(): Boolean = minimum != null - fun asProjectScoreCategories(): List = - projectScoreCategories.getOrThrow("projectScoreCategories") + /** For categorical-type project scores, the list of all categories */ + fun asCategorical(): List = categorical.getOrThrow("categorical") + /** For weighted-type project scores, the weights of each score */ fun asWeighted(): Weighted = weighted.getOrThrow("weighted") - fun asStrings(): List = strings.getOrThrow("strings") - - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") + /** For minimum-type project scores, the list of included scores */ + fun asMinimum(): List = minimum.getOrThrow("minimum") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - projectScoreCategories != null -> - visitor.visitProjectScoreCategories(projectScoreCategories) + categorical != null -> visitor.visitCategorical(categorical) weighted != null -> visitor.visitWeighted(weighted) - strings != null -> visitor.visitStrings(strings) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) + minimum != null -> visitor.visitMinimum(minimum) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Categories = apply { - if (!validated) { - if ( - projectScoreCategories == null && - weighted == null && - strings == null && - nullableVariant == null - ) { - throw BraintrustInvalidDataException("Unknown Categories: $_json") - } - projectScoreCategories?.forEach { it.validate() } - weighted?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitCategorical(categorical: List) { + categorical.forEach { it.validate() } + } + + override fun visitWeighted(weighted: Weighted) { + weighted.validate() + } + + override fun visitMinimum(minimum: List) {} + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -464,103 +824,97 @@ constructor( return true } - return other is Categories && - this.projectScoreCategories == other.projectScoreCategories && - this.weighted == other.weighted && - this.strings == other.strings && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is Categories && categorical == other.categorical && weighted == other.weighted && minimum == other.minimum /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoreCategories, - weighted, - strings, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(categorical, weighted, minimum) /* spotless:on */ - override fun toString(): String { - return when { - projectScoreCategories != null -> - "Categories{projectScoreCategories=$projectScoreCategories}" + override fun toString(): String = + when { + categorical != null -> "Categories{categorical=$categorical}" weighted != null -> "Categories{weighted=$weighted}" - strings != null -> "Categories{strings=$strings}" - nullableVariant != null -> "Categories{nullableVariant=$nullableVariant}" + minimum != null -> "Categories{minimum=$minimum}" _json != null -> "Categories{_unknown=$_json}" else -> throw IllegalStateException("Invalid Categories") } - } companion object { + /** For categorical-type project scores, the list of all categories */ @JvmStatic - fun ofProjectScoreCategories(projectScoreCategories: List) = - Categories(projectScoreCategories = projectScoreCategories) + fun ofCategorical(categorical: List) = + Categories(categorical = categorical) + /** For weighted-type project scores, the weights of each score */ @JvmStatic fun ofWeighted(weighted: Weighted) = Categories(weighted = weighted) - @JvmStatic fun ofStrings(strings: List) = Categories(strings = strings) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - Categories(nullableVariant = nullableVariant) + /** For minimum-type project scores, the list of included scores */ + @JvmStatic fun ofMinimum(minimum: List) = Categories(minimum = minimum) } + /** + * An interface that defines how to map each variant of [Categories] to a value of type [T]. + */ interface Visitor { - fun visitProjectScoreCategories(projectScoreCategories: List): T + /** For categorical-type project scores, the list of all categories */ + fun visitCategorical(categorical: List): T + /** For weighted-type project scores, the weights of each score */ fun visitWeighted(weighted: Weighted): T - fun visitStrings(strings: List): T - - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** For minimum-type project scores, the list of included scores */ + fun visitMinimum(minimum: List): T + + /** + * Maps an unknown variant of [Categories] to a value of type [T]. + * + * An instance of [Categories] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Categories: $json") } } - class Deserializer : BaseDeserializer(Categories::class) { + internal class Deserializer : BaseDeserializer(Categories::class) { override fun ObjectCodec.deserialize(node: JsonNode): Categories { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef>()) { it.forEach { it.validate() } } ?.let { - return Categories(projectScoreCategories = it, _json = json) + return Categories(categorical = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Categories(weighted = it, _json = json) } tryDeserialize(node, jacksonTypeRef>())?.let { - return Categories(strings = it, _json = json) + return Categories(minimum = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Categories(nullableVariant = it, _json = json) - } return Categories(_json = json) } } - class Serializer : BaseSerializer(Categories::class) { + internal class Serializer : BaseSerializer(Categories::class) { override fun serialize( value: Categories, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.projectScoreCategories != null -> - generator.writeObject(value.projectScoreCategories) + value.categorical != null -> generator.writeObject(value.categorical) value.weighted != null -> generator.writeObject(value.weighted) - value.strings != null -> generator.writeObject(value.strings) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) + value.minimum != null -> generator.writeObject(value.minimum) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Categories") } @@ -568,68 +922,53 @@ constructor( } /** For weighted-type project scores, the weights of each score */ - @JsonDeserialize(builder = Weighted.Builder::class) @NoAutoDetect class Weighted + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Weighted = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Weighted = apply { + if (validated) { + return@apply } - return other is Weighted && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Weighted]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Weighted]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(weighted: Weighted) = apply { - additionalProperties(weighted.additionalProperties) + additionalProperties = weighted.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -637,83 +976,50 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Weighted = Weighted(additionalProperties.toUnmodifiable()) - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Weighted]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Weighted = Weighted(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Weighted && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - private var additionalProperties: MutableMap = mutableMapOf() + override fun hashCode(): Int = hashCode - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } + override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + } + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return /* spotless:off */ other is ProjectScoreCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } - } - } + override fun toString() = + "ProjectScoreCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParams.kt index 23ff689d..8e26501a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a project_score object by its id */ class ProjectScoreDeleteParams -constructor( +private constructor( private val projectScoreId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** ProjectScore id */ fun projectScoreId(): String = projectScoreId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,147 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectScoreDeleteParams && - this.projectScoreId == other.projectScoreId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - projectScoreId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "ProjectScoreDeleteParams{projectScoreId=$projectScoreId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreDeleteParams]. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectScoreId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectScoreDeleteParams: ProjectScoreDeleteParams) = apply { - this.projectScoreId = projectScoreDeleteParams.projectScoreId - additionalQueryParams(projectScoreDeleteParams.additionalQueryParams) - additionalHeaders(projectScoreDeleteParams.additionalHeaders) - additionalBodyProperties(projectScoreDeleteParams.additionalBodyProperties) + projectScoreId = projectScoreDeleteParams.projectScoreId + additionalHeaders = projectScoreDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + projectScoreDeleteParams.additionalBodyProperties.toMutableMap() } /** ProjectScore id */ fun projectScoreId(projectScoreId: String) = apply { this.projectScoreId = projectScoreId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +193,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [ProjectScoreDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreDeleteParams = ProjectScoreDeleteParams( - checkNotNull(projectScoreId) { "`projectScoreId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectScoreId", projectScoreId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectScoreDeleteParams && projectScoreId == other.projectScoreId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectScoreId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "ProjectScoreDeleteParams{projectScoreId=$projectScoreId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPage.kt index f638afa9..904e8477 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ProjectScoreService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all project_scores. The project_scores are sorted by creation date, with the most + * recently-created project_scores coming first + */ class ProjectScoreListPage private constructor( private val projectScoresService: ProjectScoreService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ProjectScoreListPage && - this.projectScoresService == other.projectScoresService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectScoreListPage && projectScoresService == other.projectScoresService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoresService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectScoresService, params, response) /* spotless:on */ override fun toString() = "ProjectScoreListPage{projectScoresService=$projectScoresService, params=$params, response=$response}" @@ -89,25 +86,20 @@ private constructor( fun of( projectScoresService: ProjectScoreService, params: ProjectScoreListParams, - response: Response - ) = - ProjectScoreListPage( - projectScoresService, - params, - response, - ) + response: Response, + ) = ProjectScoreListPage(projectScoresService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -117,11 +109,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -131,20 +127,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectScoreListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ProjectScoreListPage]. */ @JvmStatic fun builder() = Builder() } @@ -161,22 +154,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectScoreListPage, - ) : Iterable { + class AutoPager(private val firstPage: ProjectScoreListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -185,7 +178,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPageAsync.kt index 961d9012..0f5c5540 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ProjectScoreServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all project_scores. The project_scores are sorted by creation date, with the most + * recently-created project_scores coming first + */ class ProjectScoreListPageAsync private constructor( private val projectScoresService: ProjectScoreServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ProjectScoreListPageAsync && - this.projectScoresService == other.projectScoresService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectScoreListPageAsync && projectScoresService == other.projectScoresService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoresService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectScoresService, params, response) /* spotless:on */ override fun toString() = "ProjectScoreListPageAsync{projectScoresService=$projectScoresService, params=$params, response=$response}" @@ -92,25 +88,20 @@ private constructor( fun of( projectScoresService: ProjectScoreServiceAsync, params: ProjectScoreListParams, - response: Response - ) = - ProjectScoreListPageAsync( - projectScoresService, - params, - response, - ) + response: Response, + ) = ProjectScoreListPageAsync(projectScoresService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +111,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +129,20 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectScoreListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of + * [ProjectScoreListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +159,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectScoreListPageAsync, - ) { + class AutoPager(private val firstPage: ProjectScoreListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (ProjectScore) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +188,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListParams.kt index a2d3f5fd..a1946a16 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all project_scores. The project_scores are sorted by creation date, with the most + * recently-created project_scores coming first + */ class ProjectScoreListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, @@ -31,97 +37,109 @@ constructor( private val projectScoreName: String?, private val scoreType: ScoreType?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** Name of the project_score to search for */ fun projectScoreName(): Optional = Optional.ofNullable(projectScoreName) + /** The type of the configured score */ fun scoreType(): Optional = Optional.ofNullable(scoreType) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.projectScoreName?.let { params.put("project_score_name", listOf(it.toString())) } - this.scoreType?.let { params.put("score_type", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectScoreListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.projectScoreName == other.projectScoreName && - this.scoreType == other.scoreType && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - projectId, - projectName, - projectScoreName, - scoreType, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectScoreListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, projectScoreName=$projectScoreName, scoreType=$scoreType, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + projectScoreName?.let { put("project_score_name", it) } + scoreType?.accept( + object : ScoreType.Visitor { + override fun visitProject(project: ProjectScoreType) { + put("score_type", project.asString()) + } + + override fun visitProjectScoreTypes( + projectScoreTypes: List + ) { + put("score_type", projectScoreTypes.joinToString(",") { it.asString() }) + } + } + ) + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): ProjectScoreListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ProjectScoreListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null @@ -132,22 +150,22 @@ constructor( private var projectScoreName: String? = null private var scoreType: ScoreType? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectScoreListParams: ProjectScoreListParams) = apply { - this.endingBefore = projectScoreListParams.endingBefore - this.ids = projectScoreListParams.ids - this.limit = projectScoreListParams.limit - this.orgName = projectScoreListParams.orgName - this.projectId = projectScoreListParams.projectId - this.projectName = projectScoreListParams.projectName - this.projectScoreName = projectScoreListParams.projectScoreName - this.scoreType = projectScoreListParams.scoreType - this.startingAfter = projectScoreListParams.startingAfter - additionalQueryParams(projectScoreListParams.additionalQueryParams) - additionalHeaders(projectScoreListParams.additionalHeaders) + endingBefore = projectScoreListParams.endingBefore + ids = projectScoreListParams.ids + limit = projectScoreListParams.limit + orgName = projectScoreListParams.orgName + projectId = projectScoreListParams.projectId + projectName = projectScoreListParams.projectName + projectScoreName = projectScoreListParams.projectScoreName + scoreType = projectScoreListParams.scoreType + startingAfter = projectScoreListParams.startingAfter + additionalHeaders = projectScoreListParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreListParams.additionalQueryParams.toBuilder() } /** @@ -157,55 +175,80 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** Name of the project_score to search for */ - fun projectScoreName(projectScoreName: String) = apply { + fun projectScoreName(projectScoreName: String?) = apply { this.projectScoreName = projectScoreName } - /** The type of the configured score */ - fun scoreType(scoreType: ScoreType) = apply { this.scoreType = scoreType } + /** Alias for calling [Builder.projectScoreName] with `projectScoreName.orElse(null)`. */ + fun projectScoreName(projectScoreName: Optional) = + projectScoreName(projectScoreName.getOrNull()) /** The type of the configured score */ - fun scoreType(projectScoreType: ProjectScoreType) = apply { - this.scoreType = ScoreType.ofProjectScoreType(projectScoreType) - } + fun scoreType(scoreType: ScoreType?) = apply { this.scoreType = scoreType } - /** The type of the configured score */ - fun scoreType(projectScoreTypes: List) = apply { - this.scoreType = ScoreType.ofProjectScoreTypes(projectScoreTypes) - } + /** Alias for calling [Builder.scoreType] with `scoreType.orElse(null)`. */ + fun scoreType(scoreType: Optional) = scoreType(scoreType.getOrNull()) + + /** Alias for calling [scoreType] with `ScoreType.ofProject(project)`. */ + fun scoreType(project: ProjectScoreType) = scoreType(ScoreType.ofProject(project)) + + /** + * Alias for calling [scoreType] with `ScoreType.ofProjectScoreTypes(projectScoreTypes)`. + */ + fun scoreTypeOfProjectScoreTypes(projectScoreTypes: List) = + scoreType(ScoreType.ofProjectScoreTypes(projectScoreTypes)) /** * Pagination cursor id. @@ -214,48 +257,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectScoreListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ProjectScoreListParams = ProjectScoreListParams( endingBefore, @@ -267,11 +377,15 @@ constructor( projectScoreName, scoreType, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -281,8 +395,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -305,35 +417,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -342,21 +442,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -368,12 +479,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -385,29 +496,31 @@ constructor( } } + /** The type of the configured score */ @JsonDeserialize(using = ScoreType.Deserializer::class) @JsonSerialize(using = ScoreType.Serializer::class) class ScoreType private constructor( - private val projectScoreType: ProjectScoreType? = null, + private val project: ProjectScoreType? = null, private val projectScoreTypes: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** The type of the configured score */ - fun projectScoreType(): Optional = Optional.ofNullable(projectScoreType) + fun project(): Optional = Optional.ofNullable(project) + /** The type of the configured score */ fun projectScoreTypes(): Optional> = Optional.ofNullable(projectScoreTypes) - fun isProjectScoreType(): Boolean = projectScoreType != null + fun isProject(): Boolean = project != null fun isProjectScoreTypes(): Boolean = projectScoreTypes != null - fun asProjectScoreType(): ProjectScoreType = projectScoreType.getOrThrow("projectScoreType") + /** The type of the configured score */ + fun asProject(): ProjectScoreType = project.getOrThrow("project") + /** The type of the configured score */ fun asProjectScoreTypes(): List = projectScoreTypes.getOrThrow("projectScoreTypes") @@ -415,72 +528,74 @@ constructor( fun accept(visitor: Visitor): T { return when { - projectScoreType != null -> visitor.visitProjectScoreType(projectScoreType) + project != null -> visitor.visitProject(project) projectScoreTypes != null -> visitor.visitProjectScoreTypes(projectScoreTypes) else -> visitor.unknown(_json) } } - fun validate(): ScoreType = apply { - if (!validated) { - if (projectScoreType == null && projectScoreTypes == null) { - throw BraintrustInvalidDataException("Unknown ScoreType: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is ScoreType && - this.projectScoreType == other.projectScoreType && - this.projectScoreTypes == other.projectScoreTypes + return /* spotless:off */ other is ScoreType && project == other.project && projectScoreTypes == other.projectScoreTypes /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(projectScoreType, projectScoreTypes) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(project, projectScoreTypes) /* spotless:on */ - override fun toString(): String { - return when { - projectScoreType != null -> "ScoreType{projectScoreType=$projectScoreType}" + override fun toString(): String = + when { + project != null -> "ScoreType{project=$project}" projectScoreTypes != null -> "ScoreType{projectScoreTypes=$projectScoreTypes}" _json != null -> "ScoreType{_unknown=$_json}" else -> throw IllegalStateException("Invalid ScoreType") } - } companion object { - @JvmStatic - fun ofProjectScoreType(projectScoreType: ProjectScoreType) = - ScoreType(projectScoreType = projectScoreType) + /** The type of the configured score */ + @JvmStatic fun ofProject(project: ProjectScoreType) = ScoreType(project = project) + /** The type of the configured score */ @JvmStatic fun ofProjectScoreTypes(projectScoreTypes: List) = ScoreType(projectScoreTypes = projectScoreTypes) } + /** + * An interface that defines how to map each variant of [ScoreType] to a value of type [T]. + */ interface Visitor { - fun visitProjectScoreType(projectScoreType: ProjectScoreType): T + /** The type of the configured score */ + fun visitProject(project: ProjectScoreType): T + /** The type of the configured score */ fun visitProjectScoreTypes(projectScoreTypes: List): T + /** + * Maps an unknown variant of [ScoreType] to a value of type [T]. + * + * An instance of [ScoreType] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown ScoreType: $json") } } - class Deserializer : BaseDeserializer(ScoreType::class) { + internal class Deserializer : BaseDeserializer(ScoreType::class) { override fun ObjectCodec.deserialize(node: JsonNode): ScoreType { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { - return ScoreType(projectScoreType = it, _json = json) + return ScoreType(project = it, _json = json) } tryDeserialize(node, jacksonTypeRef>())?.let { return ScoreType(projectScoreTypes = it, _json = json) @@ -490,15 +605,15 @@ constructor( } } - class Serializer : BaseSerializer(ScoreType::class) { + internal class Serializer : BaseSerializer(ScoreType::class) { override fun serialize( value: ScoreType, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.projectScoreType != null -> generator.writeObject(value.projectScoreType) + value.project != null -> generator.writeObject(value.project) value.projectScoreTypes != null -> generator.writeObject(value.projectScoreTypes) value._json != null -> generator.writeObject(value._json) @@ -507,4 +622,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectScoreListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && projectScoreName == other.projectScoreName && scoreType == other.scoreType && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, projectId, projectName, projectScoreName, scoreType, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectScoreListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, projectScoreName=$projectScoreName, scoreType=$scoreType, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParams.kt index 0b4b5f51..439137c0 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParams.kt @@ -5,13 +5,21 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec @@ -22,441 +30,794 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace project_score. If there is an existing project_score in the project with the + * same name as the one specified in the request, will replace the existing project_score with the + * provided fields + */ class ProjectScoreReplaceParams -constructor( - private val name: String, - private val projectId: String, - private val scoreType: ProjectScoreType, - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun scoreType(): ProjectScoreType = scoreType - - fun categories(): Optional = Optional.ofNullable(categories) - - fun config(): Optional = Optional.ofNullable(config) - - fun description(): Optional = Optional.ofNullable(description) - - @JvmSynthetic - internal fun getBody(): ProjectScoreReplaceBody { - return ProjectScoreReplaceBody( - name, - projectId, - scoreType, - categories, - config, - description, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the project score belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException 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 scoreType(): ProjectScoreType = body.scoreType() + + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun categories(): Optional = body.categories() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun config(): Optional = body.config() + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _scoreType(): JsonField = body._scoreType() + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _categories(): JsonField = body._categories() + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _config(): JsonField = body._config() + + /** + * 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() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams /** A project score is a user-configured score, which can be manually-labeled through the UI */ - @JsonDeserialize(builder = ProjectScoreReplaceBody.Builder::class) @NoAutoDetect - class ProjectScoreReplaceBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val scoreType: ProjectScoreType?, - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("score_type") + @ExcludeMissing + private val scoreType: JsonField = JsonMissing.of(), + @JsonProperty("categories") + @ExcludeMissing + private val categories: JsonField = JsonMissing.of(), + @JsonProperty("config") + @ExcludeMissing + private val config: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project score */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** The type of the configured score */ - @JsonProperty("score_type") fun scoreType(): ProjectScoreType? = scoreType - - @JsonProperty("categories") fun categories(): Categories? = categories - - @JsonProperty("config") fun config(): ProjectScoreConfig? = config - - /** Textual description of the project score */ - @JsonProperty("description") fun description(): String? = description + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the project score belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException 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 scoreType(): ProjectScoreType = scoreType.getRequired("score_type") + + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun categories(): Optional = + Optional.ofNullable(categories.getNullable("categories")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun config(): Optional = + Optional.ofNullable(config.getNullable("config")) + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("score_type") + @ExcludeMissing + fun _scoreType(): JsonField = scoreType + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("config") + @ExcludeMissing + fun _config(): JsonField = config + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectScoreReplaceBody && - this.name == other.name && - this.projectId == other.projectId && - this.scoreType == other.scoreType && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - scoreType, - categories, - config, - description, - additionalProperties, - ) - } - return hashCode + name() + projectId() + scoreType() + categories().ifPresent { it.validate() } + config().ifPresent { it.validate() } + description() + validated = true } - override fun toString() = - "ProjectScoreReplaceBody{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalProperties=$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() + * .projectId() + * .scoreType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var scoreType: ProjectScoreType? = null - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var scoreType: JsonField? = null + private var categories: JsonField = JsonMissing.of() + private var config: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectScoreReplaceBody: ProjectScoreReplaceBody) = apply { - this.name = projectScoreReplaceBody.name - this.projectId = projectScoreReplaceBody.projectId - this.scoreType = projectScoreReplaceBody.scoreType - this.categories = projectScoreReplaceBody.categories - this.config = projectScoreReplaceBody.config - this.description = projectScoreReplaceBody.description - additionalProperties(projectScoreReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + scoreType = body.scoreType + categories = body.categories + config = body.config + description = body.description + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project score */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the project score belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** The type of the configured score */ - @JsonProperty("score_type") - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType) = scoreType(JsonField.of(scoreType)) + + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun scoreType(scoreType: JsonField) = apply { + this.scoreType = scoreType + } - @JsonProperty("categories") - fun categories(categories: Categories) = apply { this.categories = categories } + /** For categorical-type project scores, the list of all categories */ + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { + this.categories = categories + } + + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = + categories(Categories.ofCategorical(categorical)) + + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = + categories(Categories.ofWeighted(weighted)) + + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = + categories(Categories.ofMinimum(minimum)) - @JsonProperty("config") - fun config(config: ProjectScoreConfig) = apply { this.config = config } + fun config(config: ProjectScoreConfig?) = config(JsonField.ofNullable(config)) + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { this.config = config } /** Textual description of the project score */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectScoreReplaceBody = - ProjectScoreReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scoreType) { "`scoreType` is required but was not set" }, + 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() + * .projectId() + * .scoreType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("scoreType", scoreType), categories, config, description, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && scoreType == other.scoreType && categories == other.categories && config == other.config && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectScoreReplaceParams && - this.name == other.name && - this.projectId == other.projectId && - this.scoreType == other.scoreType && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, scoreType, categories, config, description, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - scoreType, - categories, - config, - description, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectScoreReplaceParams{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, scoreType=$scoreType, categories=$categories, config=$config, description=$description, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .scoreType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreReplaceParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var projectId: String? = null - private var scoreType: ProjectScoreType? = null - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(projectScoreReplaceParams: ProjectScoreReplaceParams) = apply { - this.name = projectScoreReplaceParams.name - this.projectId = projectScoreReplaceParams.projectId - this.scoreType = projectScoreReplaceParams.scoreType - this.categories = projectScoreReplaceParams.categories - this.config = projectScoreReplaceParams.config - this.description = projectScoreReplaceParams.description - additionalQueryParams(projectScoreReplaceParams.additionalQueryParams) - additionalHeaders(projectScoreReplaceParams.additionalHeaders) - additionalBodyProperties(projectScoreReplaceParams.additionalBodyProperties) + body = projectScoreReplaceParams.body.toBuilder() + additionalHeaders = projectScoreReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreReplaceParams.additionalQueryParams.toBuilder() } /** Name of the project score */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the project score belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** The type of the configured score */ - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType) = apply { body.scoreType(scoreType) } - /** For categorical-type project scores, the list of all categories */ - fun categories(categories: Categories) = apply { this.categories = categories } + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scoreType(scoreType: JsonField) = apply { body.scoreType(scoreType) } /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(projectScoreCategories: List) = apply { - this.categories = Categories.ofProjectScoreCategories(projectScoreCategories) + fun categories(categories: Categories?) = apply { body.categories(categories) } + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { body.categories(categories) } + + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = apply { + body.categoriesOfCategorical(categorical) } - /** For categorical-type project scores, the list of all categories */ - fun categories(weighted: Categories.Weighted) = apply { - this.categories = Categories.ofWeighted(weighted) + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = apply { body.categories(weighted) } + + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = apply { body.categoriesOfMinimum(minimum) } + + fun config(config: ProjectScoreConfig?) = apply { body.config(config) } + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { body.config(config) } + + /** Textual description of the project score */ + 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) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - /** For categorical-type project scores, the list of all categories */ - fun categories(strings: List) = apply { - this.categories = Categories.ofStrings(strings) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - /** For categorical-type project scores, the list of all categories */ - fun categories(nullableVariant: Categories.NullableVariant) = apply { - this.categories = Categories.ofNullableVariant(nullableVariant) + 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 config(config: ProjectScoreConfig) = apply { this.config = config } + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - /** Textual description of the project score */ - fun description(description: String) = apply { this.description = description } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectScoreReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .scoreType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreReplaceParams = ProjectScoreReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(scoreType) { "`scoreType` is required but was not set" }, - categories, - config, - description, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** For categorical-type project scores, the list of all categories */ @JsonDeserialize(using = Categories.Deserializer::class) @JsonSerialize(using = Categories.Serializer::class) class Categories private constructor( - private val projectScoreCategories: List? = null, + private val categorical: List? = null, private val weighted: Weighted? = null, - private val strings: List? = null, - private val nullableVariant: NullableVariant? = null, + private val minimum: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(): Optional> = - Optional.ofNullable(projectScoreCategories) + fun categorical(): Optional> = Optional.ofNullable(categorical) + /** For weighted-type project scores, the weights of each score */ fun weighted(): Optional = Optional.ofNullable(weighted) - /** For minimum-type project scores, the list of included scores */ - fun strings(): Optional> = Optional.ofNullable(strings) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) + /** For minimum-type project scores, the list of included scores */ + fun minimum(): Optional> = Optional.ofNullable(minimum) - fun isProjectScoreCategories(): Boolean = projectScoreCategories != null + fun isCategorical(): Boolean = categorical != null fun isWeighted(): Boolean = weighted != null - fun isStrings(): Boolean = strings != null - - fun isNullableVariant(): Boolean = nullableVariant != null + fun isMinimum(): Boolean = minimum != null - fun asProjectScoreCategories(): List = - projectScoreCategories.getOrThrow("projectScoreCategories") + /** For categorical-type project scores, the list of all categories */ + fun asCategorical(): List = categorical.getOrThrow("categorical") + /** For weighted-type project scores, the weights of each score */ fun asWeighted(): Weighted = weighted.getOrThrow("weighted") - fun asStrings(): List = strings.getOrThrow("strings") - - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") + /** For minimum-type project scores, the list of included scores */ + fun asMinimum(): List = minimum.getOrThrow("minimum") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - projectScoreCategories != null -> - visitor.visitProjectScoreCategories(projectScoreCategories) + categorical != null -> visitor.visitCategorical(categorical) weighted != null -> visitor.visitWeighted(weighted) - strings != null -> visitor.visitStrings(strings) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) + minimum != null -> visitor.visitMinimum(minimum) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Categories = apply { - if (!validated) { - if ( - projectScoreCategories == null && - weighted == null && - strings == null && - nullableVariant == null - ) { - throw BraintrustInvalidDataException("Unknown Categories: $_json") - } - projectScoreCategories?.forEach { it.validate() } - weighted?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitCategorical(categorical: List) { + categorical.forEach { it.validate() } + } + + override fun visitWeighted(weighted: Weighted) { + weighted.validate() + } + + override fun visitMinimum(minimum: List) {} + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -464,103 +825,97 @@ constructor( return true } - return other is Categories && - this.projectScoreCategories == other.projectScoreCategories && - this.weighted == other.weighted && - this.strings == other.strings && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is Categories && categorical == other.categorical && weighted == other.weighted && minimum == other.minimum /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoreCategories, - weighted, - strings, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(categorical, weighted, minimum) /* spotless:on */ - override fun toString(): String { - return when { - projectScoreCategories != null -> - "Categories{projectScoreCategories=$projectScoreCategories}" + override fun toString(): String = + when { + categorical != null -> "Categories{categorical=$categorical}" weighted != null -> "Categories{weighted=$weighted}" - strings != null -> "Categories{strings=$strings}" - nullableVariant != null -> "Categories{nullableVariant=$nullableVariant}" + minimum != null -> "Categories{minimum=$minimum}" _json != null -> "Categories{_unknown=$_json}" else -> throw IllegalStateException("Invalid Categories") } - } companion object { + /** For categorical-type project scores, the list of all categories */ @JvmStatic - fun ofProjectScoreCategories(projectScoreCategories: List) = - Categories(projectScoreCategories = projectScoreCategories) + fun ofCategorical(categorical: List) = + Categories(categorical = categorical) + /** For weighted-type project scores, the weights of each score */ @JvmStatic fun ofWeighted(weighted: Weighted) = Categories(weighted = weighted) - @JvmStatic fun ofStrings(strings: List) = Categories(strings = strings) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - Categories(nullableVariant = nullableVariant) + /** For minimum-type project scores, the list of included scores */ + @JvmStatic fun ofMinimum(minimum: List) = Categories(minimum = minimum) } + /** + * An interface that defines how to map each variant of [Categories] to a value of type [T]. + */ interface Visitor { - fun visitProjectScoreCategories(projectScoreCategories: List): T + /** For categorical-type project scores, the list of all categories */ + fun visitCategorical(categorical: List): T + /** For weighted-type project scores, the weights of each score */ fun visitWeighted(weighted: Weighted): T - fun visitStrings(strings: List): T - - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** For minimum-type project scores, the list of included scores */ + fun visitMinimum(minimum: List): T + + /** + * Maps an unknown variant of [Categories] to a value of type [T]. + * + * An instance of [Categories] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Categories: $json") } } - class Deserializer : BaseDeserializer(Categories::class) { + internal class Deserializer : BaseDeserializer(Categories::class) { override fun ObjectCodec.deserialize(node: JsonNode): Categories { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef>()) { it.forEach { it.validate() } } ?.let { - return Categories(projectScoreCategories = it, _json = json) + return Categories(categorical = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Categories(weighted = it, _json = json) } tryDeserialize(node, jacksonTypeRef>())?.let { - return Categories(strings = it, _json = json) + return Categories(minimum = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Categories(nullableVariant = it, _json = json) - } return Categories(_json = json) } } - class Serializer : BaseSerializer(Categories::class) { + internal class Serializer : BaseSerializer(Categories::class) { override fun serialize( value: Categories, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.projectScoreCategories != null -> - generator.writeObject(value.projectScoreCategories) + value.categorical != null -> generator.writeObject(value.categorical) value.weighted != null -> generator.writeObject(value.weighted) - value.strings != null -> generator.writeObject(value.strings) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) + value.minimum != null -> generator.writeObject(value.minimum) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Categories") } @@ -568,68 +923,53 @@ constructor( } /** For weighted-type project scores, the weights of each score */ - @JsonDeserialize(builder = Weighted.Builder::class) @NoAutoDetect class Weighted + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Weighted = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Weighted = apply { + if (validated) { + return@apply } - return other is Weighted && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Weighted]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Weighted]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(weighted: Weighted) = apply { - additionalProperties(weighted.additionalProperties) + additionalProperties = weighted.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -637,83 +977,50 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Weighted = Weighted(additionalProperties.toUnmodifiable()) - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Weighted]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Weighted = Weighted(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Weighted && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - private var additionalProperties: MutableMap = mutableMapOf() + override fun hashCode(): Int = hashCode - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } + override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + } + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return /* spotless:off */ other is ProjectScoreReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } - } - } + override fun toString() = + "ProjectScoreReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParams.kt index cf6919d4..e2694fa2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a project_score object by its id */ class ProjectScoreRetrieveParams -constructor( +private constructor( private val projectScoreId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** ProjectScore id */ fun projectScoreId(): String = projectScoreId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectScoreRetrieveParams && - this.projectScoreId == other.projectScoreId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - projectScoreId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectScoreRetrieveParams{projectScoreId=$projectScoreId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreRetrieveParams]. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectScoreId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectScoreRetrieveParams: ProjectScoreRetrieveParams) = apply { - this.projectScoreId = projectScoreRetrieveParams.projectScoreId - additionalQueryParams(projectScoreRetrieveParams.additionalQueryParams) - additionalHeaders(projectScoreRetrieveParams.additionalHeaders) + projectScoreId = projectScoreRetrieveParams.projectScoreId + additionalHeaders = projectScoreRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreRetrieveParams.additionalQueryParams.toBuilder() } /** ProjectScore id */ fun projectScoreId(projectScoreId: String) = apply { this.projectScoreId = projectScoreId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectScoreRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreRetrieveParams = ProjectScoreRetrieveParams( - checkNotNull(projectScoreId) { "`projectScoreId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("projectScoreId", projectScoreId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectScoreRetrieveParams && projectScoreId == other.projectScoreId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectScoreId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectScoreRetrieveParams{projectScoreId=$projectScoreId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreType.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreType.kt index fb9ec5be..59dff6a1 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreType.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreType.kt @@ -4,81 +4,136 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonCreator -class ProjectScoreType -@JsonCreator -private constructor( - private val value: JsonField, -) : Enum { - +/** The type of the configured score */ +class ProjectScoreType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectScoreType && this.value == other.value - } - - override fun hashCode() = value.hashCode() + companion object { - override fun toString() = value.toString() + @JvmField val SLIDER = of("slider") - companion object { + @JvmField val CATEGORICAL = of("categorical") - @JvmField val SLIDER = ProjectScoreType(JsonField.of("slider")) + @JvmField val WEIGHTED = of("weighted") - @JvmField val CATEGORICAL = ProjectScoreType(JsonField.of("categorical")) + @JvmField val MINIMUM = of("minimum") - @JvmField val WEIGHTED = ProjectScoreType(JsonField.of("weighted")) + @JvmField val MAXIMUM = of("maximum") - @JvmField val MINIMUM = ProjectScoreType(JsonField.of("minimum")) + @JvmField val ONLINE = of("online") - @JvmField val ONLINE = ProjectScoreType(JsonField.of("online")) + @JvmField val FREE_FORM = of("free-form") @JvmStatic fun of(value: String) = ProjectScoreType(JsonField.of(value)) } + /** An enum containing [ProjectScoreType]'s known values. */ enum class Known { SLIDER, CATEGORICAL, WEIGHTED, MINIMUM, + MAXIMUM, ONLINE, + FREE_FORM, } + /** + * An enum containing [ProjectScoreType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ProjectScoreType] 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 { SLIDER, CATEGORICAL, WEIGHTED, MINIMUM, + MAXIMUM, ONLINE, + FREE_FORM, + /** + * An enum member indicating that [ProjectScoreType] 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) { SLIDER -> Value.SLIDER CATEGORICAL -> Value.CATEGORICAL WEIGHTED -> Value.WEIGHTED MINIMUM -> Value.MINIMUM + MAXIMUM -> Value.MAXIMUM ONLINE -> Value.ONLINE + FREE_FORM -> Value.FREE_FORM 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { SLIDER -> Known.SLIDER CATEGORICAL -> Known.CATEGORICAL WEIGHTED -> Known.WEIGHTED MINIMUM -> Known.MINIMUM + MAXIMUM -> Known.MAXIMUM ONLINE -> Known.ONLINE + FREE_FORM -> Known.FREE_FORM else -> throw BraintrustInvalidDataException("Unknown ProjectScoreType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectScoreType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParams.kt index 3d7a8fa9..f008ac19 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParams.kt @@ -5,13 +5,21 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec @@ -22,47 +30,108 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a project_score object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ class ProjectScoreUpdateParams -constructor( +private constructor( private val projectScoreId: String, - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val name: String?, - private val scoreType: ProjectScoreType?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** ProjectScore id */ fun projectScoreId(): String = projectScoreId - fun categories(): Optional = Optional.ofNullable(categories) - - fun config(): Optional = Optional.ofNullable(config) - - fun description(): Optional = Optional.ofNullable(description) - - fun name(): Optional = Optional.ofNullable(name) - - fun scoreType(): Optional = Optional.ofNullable(scoreType) - - @JvmSynthetic - internal fun getBody(): ProjectScoreUpdateBody { - return ProjectScoreUpdateBody( - categories, - config, - description, - name, - scoreType, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun categories(): Optional = body.categories() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun config(): Optional = body.config() + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scoreType(): Optional = body.scoreType() + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _categories(): JsonField = body._categories() + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _config(): JsonField = body._config() + + /** + * 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 [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 [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _scoreType(): JsonField = body._scoreType() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -72,384 +141,630 @@ constructor( } /** A project score is a user-configured score, which can be manually-labeled through the UI */ - @JsonDeserialize(builder = ProjectScoreUpdateBody.Builder::class) @NoAutoDetect - class ProjectScoreUpdateBody - internal constructor( - private val categories: Categories?, - private val config: ProjectScoreConfig?, - private val description: String?, - private val name: String?, - private val scoreType: ProjectScoreType?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("categories") + @ExcludeMissing + private val categories: JsonField = JsonMissing.of(), + @JsonProperty("config") + @ExcludeMissing + private val config: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("score_type") + @ExcludeMissing + private val scoreType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - @JsonProperty("categories") fun categories(): Categories? = categories - - @JsonProperty("config") fun config(): ProjectScoreConfig? = config - - /** Textual description of the project score */ - @JsonProperty("description") fun description(): String? = description - - /** Name of the project score */ - @JsonProperty("name") fun name(): String? = name - - /** The type of the configured score */ - @JsonProperty("score_type") fun scoreType(): ProjectScoreType? = scoreType + /** + * For categorical-type project scores, the list of all categories + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun categories(): Optional = + Optional.ofNullable(categories.getNullable("categories")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun config(): Optional = + Optional.ofNullable(config.getNullable("config")) + + /** + * Textual description of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the project score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * The type of the configured score + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun scoreType(): Optional = + Optional.ofNullable(scoreType.getNullable("score_type")) + + /** + * Returns the raw JSON value of [categories]. + * + * Unlike [categories], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("categories") + @ExcludeMissing + fun _categories(): JsonField = categories + + /** + * Returns the raw JSON value of [config]. + * + * Unlike [config], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("config") + @ExcludeMissing + fun _config(): JsonField = config + + /** + * 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 [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 [scoreType]. + * + * Unlike [scoreType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("score_type") + @ExcludeMissing + fun _scoreType(): JsonField = scoreType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectScoreUpdateBody && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.name == other.name && - this.scoreType == other.scoreType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - categories, - config, - description, - name, - scoreType, - additionalProperties, - ) - } - return hashCode + categories().ifPresent { it.validate() } + config().ifPresent { it.validate() } + description() + name() + scoreType() + validated = true } - override fun toString() = - "ProjectScoreUpdateBody{categories=$categories, config=$config, description=$description, name=$name, scoreType=$scoreType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null - private var name: String? = null - private var scoreType: ProjectScoreType? = null + private var categories: JsonField = JsonMissing.of() + private var config: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var scoreType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectScoreUpdateBody: ProjectScoreUpdateBody) = apply { - this.categories = projectScoreUpdateBody.categories - this.config = projectScoreUpdateBody.config - this.description = projectScoreUpdateBody.description - this.name = projectScoreUpdateBody.name - this.scoreType = projectScoreUpdateBody.scoreType - additionalProperties(projectScoreUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + categories = body.categories + config = body.config + description = body.description + name = body.name + scoreType = body.scoreType + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** For categorical-type project scores, the list of all categories */ + fun categories(categories: Categories?) = categories(JsonField.ofNullable(categories)) + + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) + + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { + this.categories = categories } - @JsonProperty("categories") - fun categories(categories: Categories) = apply { this.categories = categories } + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = + categories(Categories.ofCategorical(categorical)) - @JsonProperty("config") - fun config(config: ProjectScoreConfig) = apply { this.config = config } + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = + categories(Categories.ofWeighted(weighted)) + + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = + categories(Categories.ofMinimum(minimum)) + + fun config(config: ProjectScoreConfig?) = config(JsonField.ofNullable(config)) + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { this.config = config } /** Textual description of the project score */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** Name of the project score */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** The type of the configured score */ - @JsonProperty("score_type") - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType?) = scoreType(JsonField.ofNullable(scoreType)) + + /** Alias for calling [Builder.scoreType] with `scoreType.orElse(null)`. */ + fun scoreType(scoreType: Optional) = scoreType(scoreType.getOrNull()) + + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun scoreType(scoreType: JsonField) = apply { + this.scoreType = scoreType + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectScoreUpdateBody = - ProjectScoreUpdateBody( + 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. + */ + fun build(): Body = + Body( categories, config, description, name, scoreType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && categories == other.categories && config == other.config && description == other.description && name == other.name && scoreType == other.scoreType && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectScoreUpdateParams && - this.projectScoreId == other.projectScoreId && - this.categories == other.categories && - this.config == other.config && - this.description == other.description && - this.name == other.name && - this.scoreType == other.scoreType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(categories, config, description, name, scoreType, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectScoreId, - categories, - config, - description, - name, - scoreType, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectScoreUpdateParams{projectScoreId=$projectScoreId, categories=$categories, config=$config, description=$description, name=$name, scoreType=$scoreType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{categories=$categories, config=$config, description=$description, name=$name, scoreType=$scoreType, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectScoreUpdateParams]. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectScoreUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectScoreId: String? = null - private var categories: Categories? = null - private var config: ProjectScoreConfig? = null - private var description: String? = null - private var name: String? = null - private var scoreType: ProjectScoreType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectScoreUpdateParams: ProjectScoreUpdateParams) = apply { - this.projectScoreId = projectScoreUpdateParams.projectScoreId - this.categories = projectScoreUpdateParams.categories - this.config = projectScoreUpdateParams.config - this.description = projectScoreUpdateParams.description - this.name = projectScoreUpdateParams.name - this.scoreType = projectScoreUpdateParams.scoreType - additionalQueryParams(projectScoreUpdateParams.additionalQueryParams) - additionalHeaders(projectScoreUpdateParams.additionalHeaders) - additionalBodyProperties(projectScoreUpdateParams.additionalBodyProperties) + projectScoreId = projectScoreUpdateParams.projectScoreId + body = projectScoreUpdateParams.body.toBuilder() + additionalHeaders = projectScoreUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectScoreUpdateParams.additionalQueryParams.toBuilder() } /** ProjectScore id */ fun projectScoreId(projectScoreId: String) = apply { this.projectScoreId = projectScoreId } /** For categorical-type project scores, the list of all categories */ - fun categories(categories: Categories) = apply { this.categories = categories } + fun categories(categories: Categories?) = apply { body.categories(categories) } - /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(projectScoreCategories: List) = apply { - this.categories = Categories.ofProjectScoreCategories(projectScoreCategories) - } + /** Alias for calling [Builder.categories] with `categories.orElse(null)`. */ + fun categories(categories: Optional) = categories(categories.getOrNull()) - /** For categorical-type project scores, the list of all categories */ - fun categories(weighted: Categories.Weighted) = apply { - this.categories = Categories.ofWeighted(weighted) - } + /** + * Sets [Builder.categories] to an arbitrary JSON value. + * + * You should usually call [Builder.categories] with a well-typed [Categories] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun categories(categories: JsonField) = apply { body.categories(categories) } - /** For categorical-type project scores, the list of all categories */ - fun categories(strings: List) = apply { - this.categories = Categories.ofStrings(strings) + /** Alias for calling [categories] with `Categories.ofCategorical(categorical)`. */ + fun categoriesOfCategorical(categorical: List) = apply { + body.categoriesOfCategorical(categorical) } - /** For categorical-type project scores, the list of all categories */ - fun categories(nullableVariant: Categories.NullableVariant) = apply { - this.categories = Categories.ofNullableVariant(nullableVariant) - } + /** Alias for calling [categories] with `Categories.ofWeighted(weighted)`. */ + fun categories(weighted: Categories.Weighted) = apply { body.categories(weighted) } - fun config(config: ProjectScoreConfig) = apply { this.config = config } + /** Alias for calling [categories] with `Categories.ofMinimum(minimum)`. */ + fun categoriesOfMinimum(minimum: List) = apply { body.categoriesOfMinimum(minimum) } + + fun config(config: ProjectScoreConfig?) = apply { body.config(config) } + + /** Alias for calling [Builder.config] with `config.orElse(null)`. */ + fun config(config: Optional) = config(config.getOrNull()) + + /** + * Sets [Builder.config] to an arbitrary JSON value. + * + * You should usually call [Builder.config] with a well-typed [ProjectScoreConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun config(config: JsonField) = apply { body.config(config) } /** Textual description of the project score */ - fun description(description: String) = apply { this.description = description } + 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) } /** Name of the project score */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } /** The type of the configured score */ - fun scoreType(scoreType: ProjectScoreType) = apply { this.scoreType = scoreType } + fun scoreType(scoreType: ProjectScoreType?) = apply { body.scoreType(scoreType) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.scoreType] with `scoreType.orElse(null)`. */ + fun scoreType(scoreType: Optional) = scoreType(scoreType.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.scoreType] to an arbitrary JSON value. + * + * You should usually call [Builder.scoreType] with a well-typed [ProjectScoreType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun scoreType(scoreType: JsonField) = apply { body.scoreType(scoreType) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectScoreUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectScoreId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectScoreUpdateParams = ProjectScoreUpdateParams( - checkNotNull(projectScoreId) { "`projectScoreId` is required but was not set" }, - categories, - config, - description, - name, - scoreType, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectScoreId", projectScoreId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** For categorical-type project scores, the list of all categories */ @JsonDeserialize(using = Categories.Deserializer::class) @JsonSerialize(using = Categories.Serializer::class) class Categories private constructor( - private val projectScoreCategories: List? = null, + private val categorical: List? = null, private val weighted: Weighted? = null, - private val strings: List? = null, - private val nullableVariant: NullableVariant? = null, + private val minimum: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - /** For categorical-type project scores, the list of all categories */ - fun projectScoreCategories(): Optional> = - Optional.ofNullable(projectScoreCategories) + fun categorical(): Optional> = Optional.ofNullable(categorical) + /** For weighted-type project scores, the weights of each score */ fun weighted(): Optional = Optional.ofNullable(weighted) - /** For minimum-type project scores, the list of included scores */ - fun strings(): Optional> = Optional.ofNullable(strings) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) + /** For minimum-type project scores, the list of included scores */ + fun minimum(): Optional> = Optional.ofNullable(minimum) - fun isProjectScoreCategories(): Boolean = projectScoreCategories != null + fun isCategorical(): Boolean = categorical != null fun isWeighted(): Boolean = weighted != null - fun isStrings(): Boolean = strings != null - - fun isNullableVariant(): Boolean = nullableVariant != null + fun isMinimum(): Boolean = minimum != null - fun asProjectScoreCategories(): List = - projectScoreCategories.getOrThrow("projectScoreCategories") + /** For categorical-type project scores, the list of all categories */ + fun asCategorical(): List = categorical.getOrThrow("categorical") + /** For weighted-type project scores, the weights of each score */ fun asWeighted(): Weighted = weighted.getOrThrow("weighted") - fun asStrings(): List = strings.getOrThrow("strings") - - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") + /** For minimum-type project scores, the list of included scores */ + fun asMinimum(): List = minimum.getOrThrow("minimum") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - projectScoreCategories != null -> - visitor.visitProjectScoreCategories(projectScoreCategories) + categorical != null -> visitor.visitCategorical(categorical) weighted != null -> visitor.visitWeighted(weighted) - strings != null -> visitor.visitStrings(strings) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) + minimum != null -> visitor.visitMinimum(minimum) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Categories = apply { - if (!validated) { - if ( - projectScoreCategories == null && - weighted == null && - strings == null && - nullableVariant == null - ) { - throw BraintrustInvalidDataException("Unknown Categories: $_json") - } - projectScoreCategories?.forEach { it.validate() } - weighted?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitCategorical(categorical: List) { + categorical.forEach { it.validate() } + } + + override fun visitWeighted(weighted: Weighted) { + weighted.validate() + } + + override fun visitMinimum(minimum: List) {} + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -457,103 +772,97 @@ constructor( return true } - return other is Categories && - this.projectScoreCategories == other.projectScoreCategories && - this.weighted == other.weighted && - this.strings == other.strings && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is Categories && categorical == other.categorical && weighted == other.weighted && minimum == other.minimum /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectScoreCategories, - weighted, - strings, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(categorical, weighted, minimum) /* spotless:on */ - override fun toString(): String { - return when { - projectScoreCategories != null -> - "Categories{projectScoreCategories=$projectScoreCategories}" + override fun toString(): String = + when { + categorical != null -> "Categories{categorical=$categorical}" weighted != null -> "Categories{weighted=$weighted}" - strings != null -> "Categories{strings=$strings}" - nullableVariant != null -> "Categories{nullableVariant=$nullableVariant}" + minimum != null -> "Categories{minimum=$minimum}" _json != null -> "Categories{_unknown=$_json}" else -> throw IllegalStateException("Invalid Categories") } - } companion object { + /** For categorical-type project scores, the list of all categories */ @JvmStatic - fun ofProjectScoreCategories(projectScoreCategories: List) = - Categories(projectScoreCategories = projectScoreCategories) + fun ofCategorical(categorical: List) = + Categories(categorical = categorical) + /** For weighted-type project scores, the weights of each score */ @JvmStatic fun ofWeighted(weighted: Weighted) = Categories(weighted = weighted) - @JvmStatic fun ofStrings(strings: List) = Categories(strings = strings) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - Categories(nullableVariant = nullableVariant) + /** For minimum-type project scores, the list of included scores */ + @JvmStatic fun ofMinimum(minimum: List) = Categories(minimum = minimum) } + /** + * An interface that defines how to map each variant of [Categories] to a value of type [T]. + */ interface Visitor { - fun visitProjectScoreCategories(projectScoreCategories: List): T + /** For categorical-type project scores, the list of all categories */ + fun visitCategorical(categorical: List): T + /** For weighted-type project scores, the weights of each score */ fun visitWeighted(weighted: Weighted): T - fun visitStrings(strings: List): T - - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** For minimum-type project scores, the list of included scores */ + fun visitMinimum(minimum: List): T + + /** + * Maps an unknown variant of [Categories] to a value of type [T]. + * + * An instance of [Categories] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Categories: $json") } } - class Deserializer : BaseDeserializer(Categories::class) { + internal class Deserializer : BaseDeserializer(Categories::class) { override fun ObjectCodec.deserialize(node: JsonNode): Categories { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef>()) { it.forEach { it.validate() } } ?.let { - return Categories(projectScoreCategories = it, _json = json) + return Categories(categorical = it, _json = json) } tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Categories(weighted = it, _json = json) } tryDeserialize(node, jacksonTypeRef>())?.let { - return Categories(strings = it, _json = json) + return Categories(minimum = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Categories(nullableVariant = it, _json = json) - } return Categories(_json = json) } } - class Serializer : BaseSerializer(Categories::class) { + internal class Serializer : BaseSerializer(Categories::class) { override fun serialize( value: Categories, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.projectScoreCategories != null -> - generator.writeObject(value.projectScoreCategories) + value.categorical != null -> generator.writeObject(value.categorical) value.weighted != null -> generator.writeObject(value.weighted) - value.strings != null -> generator.writeObject(value.strings) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) + value.minimum != null -> generator.writeObject(value.minimum) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Categories") } @@ -561,68 +870,53 @@ constructor( } /** For weighted-type project scores, the weights of each score */ - @JsonDeserialize(builder = Weighted.Builder::class) @NoAutoDetect class Weighted + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Weighted = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Weighted = apply { + if (validated) { + return@apply } - return other is Weighted && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Weighted]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Weighted]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(weighted: Weighted) = apply { - additionalProperties(weighted.additionalProperties) + additionalProperties = weighted.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -630,83 +924,50 @@ constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): Weighted = Weighted(additionalProperties.toUnmodifiable()) - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - } - fun toBuilder() = Builder().from(this) + /** + * Returns an immutable instance of [Weighted]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Weighted = Weighted(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Weighted && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - private var additionalProperties: MutableMap = mutableMapOf() + override fun hashCode(): Int = hashCode - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } + override fun toString() = "Weighted{additionalProperties=$additionalProperties}" + } + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + return /* spotless:off */ other is ProjectScoreUpdateParams && projectScoreId == other.projectScoreId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectScoreId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } - } - } + override fun toString() = + "ProjectScoreUpdateParams{projectScoreId=$projectScoreId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectSettings.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectSettings.kt index d4a8c8cb..57bc8590 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectSettings.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectSettings.kt @@ -2,112 +2,593 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ProjectSettings.Builder::class) @NoAutoDetect class ProjectSettings +@JsonCreator private constructor( - private val comparisonKey: JsonField, - private val additionalProperties: Map, + @JsonProperty("baseline_experiment_id") + @ExcludeMissing + private val baselineExperimentId: JsonField = JsonMissing.of(), + @JsonProperty("comparison_key") + @ExcludeMissing + private val comparisonKey: JsonField = JsonMissing.of(), + @JsonProperty("spanFieldOrder") + @ExcludeMissing + private val spanFieldOrder: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * The id of the experiment to use as the default baseline for comparisons + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun baselineExperimentId(): Optional = + Optional.ofNullable(baselineExperimentId.getNullable("baseline_experiment_id")) - /** The key used to join two experiments (defaults to `input`). */ + /** + * The key used to join two experiments (defaults to `input`) + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun comparisonKey(): Optional = Optional.ofNullable(comparisonKey.getNullable("comparison_key")) - /** The key used to join two experiments (defaults to `input`). */ - @JsonProperty("comparison_key") @ExcludeMissing fun _comparisonKey() = comparisonKey + /** + * The order of the fields to display in the trace view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun spanFieldOrder(): Optional> = + Optional.ofNullable(spanFieldOrder.getNullable("spanFieldOrder")) - @JsonAnyGetter + /** + * Returns the raw JSON value of [baselineExperimentId]. + * + * Unlike [baselineExperimentId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("baseline_experiment_id") @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun _baselineExperimentId(): JsonField = baselineExperimentId - fun validate(): ProjectSettings = apply { - if (!validated) { - comparisonKey() - validated = true - } - } + /** + * Returns the raw JSON value of [comparisonKey]. + * + * Unlike [comparisonKey], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("comparison_key") + @ExcludeMissing + fun _comparisonKey(): JsonField = comparisonKey - fun toBuilder() = Builder().from(this) + /** + * Returns the raw JSON value of [spanFieldOrder]. + * + * Unlike [spanFieldOrder], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("spanFieldOrder") + @ExcludeMissing + fun _spanFieldOrder(): JsonField> = spanFieldOrder - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - return other is ProjectSettings && - this.comparisonKey == other.comparisonKey && - this.additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(comparisonKey, additionalProperties) + fun validate(): ProjectSettings = apply { + if (validated) { + return@apply } - return hashCode + + baselineExperimentId() + comparisonKey() + spanFieldOrder().ifPresent { it.forEach { it.validate() } } + validated = true } - override fun toString() = - "ProjectSettings{comparisonKey=$comparisonKey, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ProjectSettings]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectSettings]. */ + class Builder internal constructor() { + private var baselineExperimentId: JsonField = JsonMissing.of() private var comparisonKey: JsonField = JsonMissing.of() + private var spanFieldOrder: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectSettings: ProjectSettings) = apply { - this.comparisonKey = projectSettings.comparisonKey - additionalProperties(projectSettings.additionalProperties) + baselineExperimentId = projectSettings.baselineExperimentId + comparisonKey = projectSettings.comparisonKey + spanFieldOrder = projectSettings.spanFieldOrder.map { it.toMutableList() } + additionalProperties = projectSettings.additionalProperties.toMutableMap() } - /** The key used to join two experiments (defaults to `input`). */ - fun comparisonKey(comparisonKey: String) = comparisonKey(JsonField.of(comparisonKey)) + /** The id of the experiment to use as the default baseline for comparisons */ + fun baselineExperimentId(baselineExperimentId: String?) = + baselineExperimentId(JsonField.ofNullable(baselineExperimentId)) - /** The key used to join two experiments (defaults to `input`). */ - @JsonProperty("comparison_key") - @ExcludeMissing + /** + * Alias for calling [Builder.baselineExperimentId] with + * `baselineExperimentId.orElse(null)`. + */ + fun baselineExperimentId(baselineExperimentId: Optional) = + baselineExperimentId(baselineExperimentId.getOrNull()) + + /** + * Sets [Builder.baselineExperimentId] to an arbitrary JSON value. + * + * You should usually call [Builder.baselineExperimentId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun baselineExperimentId(baselineExperimentId: JsonField) = apply { + this.baselineExperimentId = baselineExperimentId + } + + /** The key used to join two experiments (defaults to `input`) */ + fun comparisonKey(comparisonKey: String?) = + comparisonKey(JsonField.ofNullable(comparisonKey)) + + /** Alias for calling [Builder.comparisonKey] with `comparisonKey.orElse(null)`. */ + fun comparisonKey(comparisonKey: Optional) = + comparisonKey(comparisonKey.getOrNull()) + + /** + * Sets [Builder.comparisonKey] to an arbitrary JSON value. + * + * You should usually call [Builder.comparisonKey] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun comparisonKey(comparisonKey: JsonField) = apply { this.comparisonKey = comparisonKey } + /** The order of the fields to display in the trace view */ + fun spanFieldOrder(spanFieldOrder: List?) = + spanFieldOrder(JsonField.ofNullable(spanFieldOrder)) + + /** Alias for calling [Builder.spanFieldOrder] with `spanFieldOrder.orElse(null)`. */ + fun spanFieldOrder(spanFieldOrder: Optional>) = + spanFieldOrder(spanFieldOrder.getOrNull()) + + /** + * Sets [Builder.spanFieldOrder] to an arbitrary JSON value. + * + * You should usually call [Builder.spanFieldOrder] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun spanFieldOrder(spanFieldOrder: JsonField>) = apply { + this.spanFieldOrder = spanFieldOrder.map { it.toMutableList() } + } + + /** + * Adds a single [SpanFieldOrder] to [Builder.spanFieldOrder]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSpanFieldOrder(spanFieldOrder: SpanFieldOrder) = apply { + this.spanFieldOrder = + (this.spanFieldOrder ?: JsonField.of(mutableListOf())).also { + checkKnown("spanFieldOrder", it).add(spanFieldOrder) + } + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ProjectSettings]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ProjectSettings = - ProjectSettings(comparisonKey, additionalProperties.toUnmodifiable()) + ProjectSettings( + baselineExperimentId, + comparisonKey, + (spanFieldOrder ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) } + + @NoAutoDetect + class SpanFieldOrder + @JsonCreator + private constructor( + @JsonProperty("column_id") + @ExcludeMissing + private val columnId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("position") + @ExcludeMissing + private val position: JsonField = JsonMissing.of(), + @JsonProperty("layout") + @ExcludeMissing + private val layout: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 columnId(): String = columnId.getRequired("column_id") + + /** + * @throws BraintrustInvalidDataException 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 objectType(): String = objectType.getRequired("object_type") + + /** + * @throws BraintrustInvalidDataException 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 position(): String = position.getRequired("position") + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun layout(): Optional = Optional.ofNullable(layout.getNullable("layout")) + + /** + * Returns the raw JSON value of [columnId]. + * + * Unlike [columnId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("column_id") @ExcludeMissing fun _columnId(): JsonField = columnId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [position]. + * + * Unlike [position], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("position") @ExcludeMissing fun _position(): JsonField = position + + /** + * Returns the raw JSON value of [layout]. + * + * Unlike [layout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("layout") @ExcludeMissing fun _layout(): JsonField = layout + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): SpanFieldOrder = apply { + if (validated) { + return@apply + } + + columnId() + objectType() + position() + layout() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanFieldOrder]. + * + * The following fields are required: + * ```java + * .columnId() + * .objectType() + * .position() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanFieldOrder]. */ + class Builder internal constructor() { + + private var columnId: JsonField? = null + private var objectType: JsonField? = null + private var position: JsonField? = null + private var layout: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(spanFieldOrder: SpanFieldOrder) = apply { + columnId = spanFieldOrder.columnId + objectType = spanFieldOrder.objectType + position = spanFieldOrder.position + layout = spanFieldOrder.layout + additionalProperties = spanFieldOrder.additionalProperties.toMutableMap() + } + + fun columnId(columnId: String) = columnId(JsonField.of(columnId)) + + /** + * Sets [Builder.columnId] to an arbitrary JSON value. + * + * You should usually call [Builder.columnId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun columnId(columnId: JsonField) = apply { this.columnId = columnId } + + fun objectType(objectType: String) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { this.objectType = objectType } + + fun position(position: String) = position(JsonField.of(position)) + + /** + * Sets [Builder.position] to an arbitrary JSON value. + * + * You should usually call [Builder.position] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun position(position: JsonField) = apply { this.position = position } + + fun layout(layout: Layout?) = layout(JsonField.ofNullable(layout)) + + /** Alias for calling [Builder.layout] with `layout.orElse(null)`. */ + fun layout(layout: Optional) = layout(layout.getOrNull()) + + /** + * Sets [Builder.layout] to an arbitrary JSON value. + * + * You should usually call [Builder.layout] with a well-typed [Layout] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun layout(layout: JsonField) = apply { this.layout = layout } + + 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 [SpanFieldOrder]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .columnId() + * .objectType() + * .position() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanFieldOrder = + SpanFieldOrder( + checkRequired("columnId", columnId), + checkRequired("objectType", objectType), + checkRequired("position", position), + layout, + additionalProperties.toImmutable(), + ) + } + + class Layout @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 FULL = of("full") + + @JvmField val TWO_COLUMN = of("two_column") + + @JvmStatic fun of(value: String) = Layout(JsonField.of(value)) + } + + /** An enum containing [Layout]'s known values. */ + enum class Known { + FULL, + TWO_COLUMN, + } + + /** + * An enum containing [Layout]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Layout] 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 { + FULL, + TWO_COLUMN, + /** + * An enum member indicating that [Layout] 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) { + FULL -> Value.FULL + TWO_COLUMN -> Value.TWO_COLUMN + 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + FULL -> Known.FULL + TWO_COLUMN -> Known.TWO_COLUMN + else -> throw BraintrustInvalidDataException("Unknown Layout: $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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Layout && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanFieldOrder && columnId == other.columnId && objectType == other.objectType && position == other.position && layout == other.layout && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(columnId, objectType, position, layout, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SpanFieldOrder{columnId=$columnId, objectType=$objectType, position=$position, layout=$layout, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectSettings && baselineExperimentId == other.baselineExperimentId && comparisonKey == other.comparisonKey && spanFieldOrder == other.spanFieldOrder && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(baselineExperimentId, comparisonKey, spanFieldOrder, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectSettings{baselineExperimentId=$baselineExperimentId, comparisonKey=$comparisonKey, spanFieldOrder=$spanFieldOrder, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTag.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTag.kt index 61b80ba9..180ffb4e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTag.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTag.kt @@ -7,237 +7,361 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * A project tag is a user-configured tag for tracking and filtering your experiments, logs, and * other data */ -@JsonDeserialize(builder = ProjectTag.Builder::class) @NoAutoDetect class ProjectTag +@JsonCreator private constructor( - private val id: JsonField, - private val projectId: JsonField, - private val userId: JsonField, - private val created: JsonField, - private val name: JsonField, - private val description: JsonField, - private val color: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("color") @ExcludeMissing private val color: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the project tag */ + /** + * Unique identifier for the project tag + * + * @throws BraintrustInvalidDataException 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") - /** Unique identifier for the project that the project tag belongs under */ + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the project tag belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + /** + * @throws BraintrustInvalidDataException 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 userId(): String = userId.getRequired("user_id") - /** Date of project tag creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun color(): Optional = Optional.ofNullable(color.getNullable("color")) - /** Name of the project tag */ - fun name(): String = name.getRequired("name") + /** + * Date of project tag creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Textual description of the project tag */ + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun description(): Optional = Optional.ofNullable(description.getNullable("description")) - /** Color of the tag for the UI */ - fun color(): Optional = Optional.ofNullable(color.getNullable("color")) - - /** Unique identifier for the project tag */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId - - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId - - /** Date of project tag creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** Name of the project tag */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Textual description of the project tag */ - @JsonProperty("description") @ExcludeMissing fun _description() = description - - /** Color of the tag for the UI */ - @JsonProperty("color") @ExcludeMissing fun _color() = color + /** + * 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 [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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("color") @ExcludeMissing fun _color(): JsonField = color + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ProjectTag = apply { - if (!validated) { - id() - projectId() - userId() - created() - name() - description() - color() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ProjectTag = apply { + if (validated) { + return@apply } - return other is ProjectTag && - this.id == other.id && - this.projectId == other.projectId && - this.userId == other.userId && - this.created == other.created && - this.name == other.name && - this.description == other.description && - this.color == other.color && - this.additionalProperties == other.additionalProperties + id() + name() + projectId() + userId() + color() + created() + description() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - projectId, - userId, - created, - name, - description, - color, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectTag{id=$id, projectId=$projectId, userId=$userId, created=$created, name=$name, description=$description, color=$color, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTag]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .userId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ProjectTag]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var userId: JsonField? = null + private var color: JsonField = JsonMissing.of() private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() - private var color: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectTag: ProjectTag) = apply { - this.id = projectTag.id - this.projectId = projectTag.projectId - this.userId = projectTag.userId - this.created = projectTag.created - this.name = projectTag.name - this.description = projectTag.description - this.color = projectTag.color - additionalProperties(projectTag.additionalProperties) + id = projectTag.id + name = projectTag.name + projectId = projectTag.projectId + userId = projectTag.userId + color = projectTag.color + created = projectTag.created + description = projectTag.description + additionalProperties = projectTag.additionalProperties.toMutableMap() } /** Unique identifier for the project tag */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the project tag */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } + + /** Name of the project tag */ + 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 } /** Unique identifier for the project that the project tag belongs under */ fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") - @ExcludeMissing + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun projectId(projectId: JsonField) = apply { this.projectId = projectId } fun userId(userId: String) = userId(JsonField.of(userId)) - @JsonProperty("user_id") - @ExcludeMissing + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun userId(userId: JsonField) = apply { this.userId = userId } - /** Date of project tag creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - - /** Date of project tag creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** Color of the tag for the UI */ + fun color(color: String?) = color(JsonField.ofNullable(color)) - /** Name of the project tag */ - fun name(name: String) = name(JsonField.of(name)) + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) - /** Name of the project tag */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun color(color: JsonField) = apply { this.color = color } - /** Textual description of the project tag */ - fun description(description: String) = description(JsonField.of(description)) + /** Date of project tag creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } /** Textual description of the project tag */ - @JsonProperty("description") - @ExcludeMissing + 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 } - /** Color of the tag for the UI */ - fun color(color: String) = color(JsonField.of(color)) - - /** Color of the tag for the UI */ - @JsonProperty("color") - @ExcludeMissing - fun color(color: JsonField) = apply { this.color = color } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ProjectTag]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .userId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTag = ProjectTag( - id, - projectId, - userId, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("userId", userId), + color, created, - name, description, - color, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTag && id == other.id && name == other.name && projectId == other.projectId && userId == other.userId && color == other.color && created == other.created && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, projectId, userId, color, created, description, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ProjectTag{id=$id, name=$name, projectId=$projectId, userId=$userId, color=$color, created=$created, description=$description, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagCreateParams.kt index 9275324e..ddb134a6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagCreateParams.kt @@ -3,313 +3,590 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new project_tag. If there is an existing project_tag in the project with the same name + * as the one specified in the request, will return the existing project_tag unmodified + */ class ProjectTagCreateParams -constructor( - private val name: String, - private val projectId: String, - private val color: String?, - private val description: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun color(): Optional = Optional.ofNullable(color) - - fun description(): Optional = Optional.ofNullable(description) - - @JvmSynthetic - internal fun getBody(): ProjectTagCreateBody { - return ProjectTagCreateBody( - name, - projectId, - color, - description, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the project tag belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun color(): Optional = body.color() + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _color(): JsonField = body._color() + + /** + * 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() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ProjectTagCreateBody.Builder::class) @NoAutoDetect - class ProjectTagCreateBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val color: String?, - private val description: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("color") + @ExcludeMissing + private val color: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project tag */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** Color of the tag for the UI */ - @JsonProperty("color") fun color(): String? = color - - /** Textual description of the project tag */ - @JsonProperty("description") fun description(): String? = description + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the project tag belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun color(): Optional = Optional.ofNullable(color.getNullable("color")) + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("color") @ExcludeMissing fun _color(): JsonField = color + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectTagCreateBody && - this.name == other.name && - this.projectId == other.projectId && - this.color == other.color && - this.description == other.description && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - color, - description, - additionalProperties, - ) - } - return hashCode + name() + projectId() + color() + description() + validated = true } - override fun toString() = - "ProjectTagCreateBody{name=$name, projectId=$projectId, color=$color, description=$description, additionalProperties=$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() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var color: String? = null - private var description: String? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var color: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectTagCreateBody: ProjectTagCreateBody) = apply { - this.name = projectTagCreateBody.name - this.projectId = projectTagCreateBody.projectId - this.color = projectTagCreateBody.color - this.description = projectTagCreateBody.description - additionalProperties(projectTagCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + color = body.color + description = body.description + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project tag */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Color of the tag for the UI */ - @JsonProperty("color") fun color(color: String) = apply { this.color = color } + fun color(color: String?) = color(JsonField.ofNullable(color)) + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun color(color: JsonField) = apply { this.color = color } /** Textual description of the project tag */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectTagCreateBody = - ProjectTagCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, + 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() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), color, description, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && color == other.color && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectTagCreateParams && - this.name == other.name && - this.projectId == other.projectId && - this.color == other.color && - this.description == other.description && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, color, description, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - color, - description, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectTagCreateParams{name=$name, projectId=$projectId, color=$color, description=$description, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, color=$color, description=$description, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var color: String? = null - private var description: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectTagCreateParams: ProjectTagCreateParams) = apply { - this.name = projectTagCreateParams.name - this.projectId = projectTagCreateParams.projectId - this.color = projectTagCreateParams.color - this.description = projectTagCreateParams.description - additionalQueryParams(projectTagCreateParams.additionalQueryParams) - additionalHeaders(projectTagCreateParams.additionalHeaders) - additionalBodyProperties(projectTagCreateParams.additionalBodyProperties) + body = projectTagCreateParams.body.toBuilder() + additionalHeaders = projectTagCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagCreateParams.additionalQueryParams.toBuilder() } /** Name of the project tag */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the project tag belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Color of the tag for the UI */ - fun color(color: String) = apply { this.color = color } + fun color(color: String?) = apply { body.color(color) } + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun color(color: JsonField) = apply { body.color(color) } /** Textual description of the project tag */ - fun description(description: String) = apply { this.description = description } + fun description(description: String?) = apply { body.description(description) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * 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) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectTagCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTagCreateParams = ProjectTagCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - color, - description, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectTagCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParams.kt index 26f9294d..9e495e9a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a project_tag object by its id */ class ProjectTagDeleteParams -constructor( +private constructor( private val projectTagId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** ProjectTag id */ fun projectTagId(): String = projectTagId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,147 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectTagDeleteParams && - this.projectTagId == other.projectTagId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - projectTagId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "ProjectTagDeleteParams{projectTagId=$projectTagId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagDeleteParams]. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectTagId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(projectTagDeleteParams: ProjectTagDeleteParams) = apply { - this.projectTagId = projectTagDeleteParams.projectTagId - additionalQueryParams(projectTagDeleteParams.additionalQueryParams) - additionalHeaders(projectTagDeleteParams.additionalHeaders) - additionalBodyProperties(projectTagDeleteParams.additionalBodyProperties) + projectTagId = projectTagDeleteParams.projectTagId + additionalHeaders = projectTagDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + projectTagDeleteParams.additionalBodyProperties.toMutableMap() } /** ProjectTag id */ fun projectTagId(projectTagId: String) = apply { this.projectTagId = projectTagId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +193,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [ProjectTagDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTagDeleteParams = ProjectTagDeleteParams( - checkNotNull(projectTagId) { "`projectTagId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectTagId", projectTagId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagDeleteParams && projectTagId == other.projectTagId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectTagId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "ProjectTagDeleteParams{projectTagId=$projectTagId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPage.kt index 065e040c..59ff4610 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ProjectTagService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all project_tags. The project_tags are sorted by creation date, with the most + * recently-created project_tags coming first + */ class ProjectTagListPage private constructor( private val projectTagsService: ProjectTagService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ProjectTagListPage && - this.projectTagsService == other.projectTagsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectTagListPage && projectTagsService == other.projectTagsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectTagsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectTagsService, params, response) /* spotless:on */ override fun toString() = "ProjectTagListPage{projectTagsService=$projectTagsService, params=$params, response=$response}" @@ -89,25 +86,20 @@ private constructor( fun of( projectTagsService: ProjectTagService, params: ProjectTagListParams, - response: Response - ) = - ProjectTagListPage( - projectTagsService, - params, - response, - ) + response: Response, + ) = ProjectTagListPage(projectTagsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -117,11 +109,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -131,20 +127,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectTagListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ProjectTagListPage]. */ @JvmStatic fun builder() = Builder() } @@ -161,22 +154,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectTagListPage, - ) : Iterable { + class AutoPager(private val firstPage: ProjectTagListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -185,7 +178,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPageAsync.kt index 403a1798..d7ff05b7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ProjectTagServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all project_tags. The project_tags are sorted by creation date, with the most + * recently-created project_tags coming first + */ class ProjectTagListPageAsync private constructor( private val projectTagsService: ProjectTagServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ProjectTagListPageAsync && - this.projectTagsService == other.projectTagsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ProjectTagListPageAsync && projectTagsService == other.projectTagsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - projectTagsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectTagsService, params, response) /* spotless:on */ override fun toString() = "ProjectTagListPageAsync{projectTagsService=$projectTagsService, params=$params, response=$response}" @@ -92,25 +88,20 @@ private constructor( fun of( projectTagsService: ProjectTagServiceAsync, params: ProjectTagListParams, - response: Response - ) = - ProjectTagListPageAsync( - projectTagsService, - params, - response, - ) + response: Response, + ) = ProjectTagListPageAsync(projectTagsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -120,11 +111,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -134,20 +129,19 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ProjectTagListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagListPageAsync]. + */ @JvmStatic fun builder() = Builder() } @@ -164,27 +158,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ProjectTagListPageAsync, - ) { + class AutoPager(private val firstPage: ProjectTagListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (ProjectTag) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -193,7 +187,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListParams.kt index 893d676e..9bc9a039 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all project_tags. The project_tags are sorted by creation date, with the most + * recently-created project_tags coming first + */ class ProjectTagListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, @@ -30,92 +36,93 @@ constructor( private val projectName: String?, private val projectTagName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** Name of the project_tag to search for */ fun projectTagName(): Optional = Optional.ofNullable(projectTagName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.projectTagName?.let { params.put("project_tag_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectTagListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.projectTagName == other.projectTagName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - projectId, - projectName, - projectTagName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectTagListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, projectTagName=$projectTagName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + projectTagName?.let { put("project_tag_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): ProjectTagListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [ProjectTagListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null @@ -125,21 +132,21 @@ constructor( private var projectName: String? = null private var projectTagName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectTagListParams: ProjectTagListParams) = apply { - this.endingBefore = projectTagListParams.endingBefore - this.ids = projectTagListParams.ids - this.limit = projectTagListParams.limit - this.orgName = projectTagListParams.orgName - this.projectId = projectTagListParams.projectId - this.projectName = projectTagListParams.projectName - this.projectTagName = projectTagListParams.projectTagName - this.startingAfter = projectTagListParams.startingAfter - additionalQueryParams(projectTagListParams.additionalQueryParams) - additionalHeaders(projectTagListParams.additionalHeaders) + endingBefore = projectTagListParams.endingBefore + ids = projectTagListParams.ids + limit = projectTagListParams.limit + orgName = projectTagListParams.orgName + projectId = projectTagListParams.projectId + projectName = projectTagListParams.projectName + projectTagName = projectTagListParams.projectTagName + startingAfter = projectTagListParams.startingAfter + additionalHeaders = projectTagListParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagListParams.additionalQueryParams.toBuilder() } /** @@ -149,40 +156,63 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** Name of the project_tag to search for */ - fun projectTagName(projectTagName: String) = apply { this.projectTagName = projectTagName } + fun projectTagName(projectTagName: String?) = apply { this.projectTagName = projectTagName } + + /** Alias for calling [Builder.projectTagName] with `projectTagName.orElse(null)`. */ + fun projectTagName(projectTagName: Optional) = + projectTagName(projectTagName.getOrNull()) /** * Pagination cursor id. @@ -191,48 +221,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectTagListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ProjectTagListParams = ProjectTagListParams( endingBefore, @@ -243,11 +340,15 @@ constructor( projectName, projectTagName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -257,8 +358,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -281,35 +380,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -318,21 +405,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -344,12 +442,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -360,4 +458,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && projectTagName == other.projectTagName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, projectId, projectName, projectTagName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectTagListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, projectTagName=$projectTagName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParams.kt index 28a4613d..d4b0801e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParams.kt @@ -3,313 +3,591 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace project_tag. If there is an existing project_tag in the project with the same + * name as the one specified in the request, will replace the existing project_tag with the provided + * fields + */ class ProjectTagReplaceParams -constructor( - private val name: String, - private val projectId: String, - private val color: String?, - private val description: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun color(): Optional = Optional.ofNullable(color) - - fun description(): Optional = Optional.ofNullable(description) - - @JvmSynthetic - internal fun getBody(): ProjectTagReplaceBody { - return ProjectTagReplaceBody( - name, - projectId, - color, - description, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the project tag belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun color(): Optional = body.color() + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _color(): JsonField = body._color() + + /** + * 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() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ProjectTagReplaceBody.Builder::class) @NoAutoDetect - class ProjectTagReplaceBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val color: String?, - private val description: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("color") + @ExcludeMissing + private val color: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project tag */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** Color of the tag for the UI */ - @JsonProperty("color") fun color(): String? = color - - /** Textual description of the project tag */ - @JsonProperty("description") fun description(): String? = description + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the project tag belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun color(): Optional = Optional.ofNullable(color.getNullable("color")) + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("color") @ExcludeMissing fun _color(): JsonField = color + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectTagReplaceBody && - this.name == other.name && - this.projectId == other.projectId && - this.color == other.color && - this.description == other.description && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - color, - description, - additionalProperties, - ) - } - return hashCode + name() + projectId() + color() + description() + validated = true } - override fun toString() = - "ProjectTagReplaceBody{name=$name, projectId=$projectId, color=$color, description=$description, additionalProperties=$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() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var color: String? = null - private var description: String? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var color: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectTagReplaceBody: ProjectTagReplaceBody) = apply { - this.name = projectTagReplaceBody.name - this.projectId = projectTagReplaceBody.projectId - this.color = projectTagReplaceBody.color - this.description = projectTagReplaceBody.description - additionalProperties(projectTagReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + color = body.color + description = body.description + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project tag */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the project tag belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Color of the tag for the UI */ - @JsonProperty("color") fun color(color: String) = apply { this.color = color } + fun color(color: String?) = color(JsonField.ofNullable(color)) + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun color(color: JsonField) = apply { this.color = color } /** Textual description of the project tag */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectTagReplaceBody = - ProjectTagReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, + 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() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), color, description, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && color == other.color && description == other.description && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectTagReplaceParams && - this.name == other.name && - this.projectId == other.projectId && - this.color == other.color && - this.description == other.description && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, color, description, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - color, - description, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectTagReplaceParams{name=$name, projectId=$projectId, color=$color, description=$description, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, color=$color, description=$description, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagReplaceParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var color: String? = null - private var description: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectTagReplaceParams: ProjectTagReplaceParams) = apply { - this.name = projectTagReplaceParams.name - this.projectId = projectTagReplaceParams.projectId - this.color = projectTagReplaceParams.color - this.description = projectTagReplaceParams.description - additionalQueryParams(projectTagReplaceParams.additionalQueryParams) - additionalHeaders(projectTagReplaceParams.additionalHeaders) - additionalBodyProperties(projectTagReplaceParams.additionalBodyProperties) + body = projectTagReplaceParams.body.toBuilder() + additionalHeaders = projectTagReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagReplaceParams.additionalQueryParams.toBuilder() } /** Name of the project tag */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the project tag belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Color of the tag for the UI */ - fun color(color: String) = apply { this.color = color } + fun color(color: String?) = apply { body.color(color) } + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun color(color: JsonField) = apply { body.color(color) } /** Textual description of the project tag */ - fun description(description: String) = apply { this.description = description } + fun description(description: String?) = apply { body.description(description) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * 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) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectTagReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTagReplaceParams = ProjectTagReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - color, - description, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectTagReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParams.kt index 1fa19f4b..36ea7037 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a project_tag object by its id */ class ProjectTagRetrieveParams -constructor( +private constructor( private val projectTagId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** ProjectTag id */ fun projectTagId(): String = projectTagId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ProjectTagRetrieveParams && - this.projectTagId == other.projectTagId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - projectTagId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ProjectTagRetrieveParams{projectTagId=$projectTagId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagRetrieveParams]. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectTagId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(projectTagRetrieveParams: ProjectTagRetrieveParams) = apply { - this.projectTagId = projectTagRetrieveParams.projectTagId - additionalQueryParams(projectTagRetrieveParams.additionalQueryParams) - additionalHeaders(projectTagRetrieveParams.additionalHeaders) + projectTagId = projectTagRetrieveParams.projectTagId + additionalHeaders = projectTagRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagRetrieveParams.additionalQueryParams.toBuilder() } /** ProjectTag id */ fun projectTagId(projectTagId: String) = apply { this.projectTagId = projectTagId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [ProjectTagRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTagRetrieveParams = ProjectTagRetrieveParams( - checkNotNull(projectTagId) { "`projectTagId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("projectTagId", projectTagId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagRetrieveParams && projectTagId == other.projectTagId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectTagId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectTagRetrieveParams{projectTagId=$projectTagId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParams.kt index e8f94d38..6a457c6e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParams.kt @@ -3,49 +3,97 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a project_tag object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ class ProjectTagUpdateParams -constructor( +private constructor( private val projectTagId: String, - private val color: String?, - private val description: String?, - private val name: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** ProjectTag id */ fun projectTagId(): String = projectTagId - fun color(): Optional = Optional.ofNullable(color) - - fun description(): Optional = Optional.ofNullable(description) - - fun name(): Optional = Optional.ofNullable(name) - - @JvmSynthetic - internal fun getBody(): ProjectTagUpdateBody { - return ProjectTagUpdateBody( - color, - description, - name, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun color(): Optional = body.color() + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _color(): JsonField = body._color() + + /** + * 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 [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _name(): JsonField = body._name() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -54,255 +102,430 @@ constructor( } } - @JsonDeserialize(builder = ProjectTagUpdateBody.Builder::class) @NoAutoDetect - class ProjectTagUpdateBody - internal constructor( - private val color: String?, - private val description: String?, - private val name: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("color") + @ExcludeMissing + private val color: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Color of the tag for the UI */ - @JsonProperty("color") fun color(): String? = color + /** + * Color of the tag for the UI + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun color(): Optional = Optional.ofNullable(color.getNullable("color")) + + /** + * Textual description of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the project tag + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Returns the raw JSON value of [color]. + * + * Unlike [color], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("color") @ExcludeMissing fun _color(): JsonField = color + + /** + * 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 - /** Textual description of the project tag */ - @JsonProperty("description") fun description(): String? = description - - /** Name of the project tag */ - @JsonProperty("name") fun name(): String? = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectTagUpdateBody && - this.color == other.color && - this.description == other.description && - this.name == other.name && - this.additionalProperties == other.additionalProperties + color() + description() + name() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - color, - description, - name, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectTagUpdateBody{color=$color, description=$description, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var color: String? = null - private var description: String? = null - private var name: String? = null + private var color: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectTagUpdateBody: ProjectTagUpdateBody) = apply { - this.color = projectTagUpdateBody.color - this.description = projectTagUpdateBody.description - this.name = projectTagUpdateBody.name - additionalProperties(projectTagUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + color = body.color + description = body.description + name = body.name + additionalProperties = body.additionalProperties.toMutableMap() } /** Color of the tag for the UI */ - @JsonProperty("color") fun color(color: String) = apply { this.color = color } + fun color(color: String?) = color(JsonField.ofNullable(color)) + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun color(color: JsonField) = apply { this.color = color } /** Textual description of the project tag */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** Name of the project tag */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectTagUpdateBody = - ProjectTagUpdateBody( - color, - description, - name, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(color, description, name, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && color == other.color && description == other.description && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectTagUpdateParams && - this.projectTagId == other.projectTagId && - this.color == other.color && - this.description == other.description && - this.name == other.name && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(color, description, name, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectTagId, - color, - description, - name, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectTagUpdateParams{projectTagId=$projectTagId, color=$color, description=$description, name=$name, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{color=$color, description=$description, name=$name, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectTagUpdateParams]. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectTagUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectTagId: String? = null - private var color: String? = null - private var description: String? = null - private var name: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectTagUpdateParams: ProjectTagUpdateParams) = apply { - this.projectTagId = projectTagUpdateParams.projectTagId - this.color = projectTagUpdateParams.color - this.description = projectTagUpdateParams.description - this.name = projectTagUpdateParams.name - additionalQueryParams(projectTagUpdateParams.additionalQueryParams) - additionalHeaders(projectTagUpdateParams.additionalHeaders) - additionalBodyProperties(projectTagUpdateParams.additionalBodyProperties) + projectTagId = projectTagUpdateParams.projectTagId + body = projectTagUpdateParams.body.toBuilder() + additionalHeaders = projectTagUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectTagUpdateParams.additionalQueryParams.toBuilder() } /** ProjectTag id */ fun projectTagId(projectTagId: String) = apply { this.projectTagId = projectTagId } /** Color of the tag for the UI */ - fun color(color: String) = apply { this.color = color } + fun color(color: String?) = apply { body.color(color) } + + /** Alias for calling [Builder.color] with `color.orElse(null)`. */ + fun color(color: Optional) = color(color.getOrNull()) + + /** + * Sets [Builder.color] to an arbitrary JSON value. + * + * You should usually call [Builder.color] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun color(color: JsonField) = apply { body.color(color) } /** Textual description of the project tag */ - fun description(description: String) = apply { this.description = description } + 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) } /** Name of the project tag */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectTagUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectTagId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectTagUpdateParams = ProjectTagUpdateParams( - checkNotNull(projectTagId) { "`projectTagId` is required but was not set" }, - color, - description, - name, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectTagId", projectTagId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectTagUpdateParams && projectTagId == other.projectTagId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectTagId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectTagUpdateParams{projectTagId=$projectTagId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectUpdateParams.kt index b9770377..3c6ecfc1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ProjectUpdateParams.kt @@ -3,45 +3,83 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a project object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class ProjectUpdateParams -constructor( +private constructor( private val projectId: String, - private val name: String?, - private val settings: ProjectSettings?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Project id */ fun projectId(): String = projectId - fun name(): Optional = Optional.ofNullable(name) + /** + * Name of the project + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() - fun settings(): Optional = Optional.ofNullable(settings) + /** + * Project settings. Patch operations replace all settings, so make sure you include all + * settings you want to keep. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settings(): Optional = body.settings() - @JvmSynthetic - internal fun getBody(): ProjectUpdateBody { - return ProjectUpdateBody( - name, - settings, - additionalBodyProperties, - ) - } + /** + * 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 [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _settings(): JsonField = body._settings() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -50,244 +88,385 @@ constructor( } } - @JsonDeserialize(builder = ProjectUpdateBody.Builder::class) @NoAutoDetect - class ProjectUpdateBody - internal constructor( - private val name: String?, - private val settings: ProjectSettings?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("settings") + @ExcludeMissing + private val settings: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the project */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the project + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) /** * Project settings. Patch operations replace all settings, so make sure you include all * settings you want to keep. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("settings") fun settings(): ProjectSettings? = settings + fun settings(): Optional = + Optional.ofNullable(settings.getNullable("settings")) + + /** + * 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 [settings]. + * + * Unlike [settings], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settings") + @ExcludeMissing + fun _settings(): JsonField = settings @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ProjectUpdateBody && - this.name == other.name && - this.settings == other.settings && - this.additionalProperties == other.additionalProperties + name() + settings().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - settings, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ProjectUpdateBody{name=$name, settings=$settings, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var settings: ProjectSettings? = null + private var name: JsonField = JsonMissing.of() + private var settings: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(projectUpdateBody: ProjectUpdateBody) = apply { - this.name = projectUpdateBody.name - this.settings = projectUpdateBody.settings - additionalProperties(projectUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + settings = body.settings + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the project */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** * Project settings. Patch operations replace all settings, so make sure you include all * settings you want to keep. */ - @JsonProperty("settings") - fun settings(settings: ProjectSettings) = apply { this.settings = settings } + fun settings(settings: ProjectSettings?) = settings(JsonField.ofNullable(settings)) + + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [ProjectSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { this.settings = settings } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ProjectUpdateBody = - ProjectUpdateBody( - name, - settings, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(name, settings, additionalProperties.toImmutable()) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && settings == other.settings && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ProjectUpdateParams && - this.projectId == other.projectId && - this.name == other.name && - this.settings == other.settings && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, settings, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - projectId, - name, - settings, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ProjectUpdateParams{projectId=$projectId, name=$name, settings=$settings, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, settings=$settings, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ProjectUpdateParams]. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ProjectUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var projectId: String? = null - private var name: String? = null - private var settings: ProjectSettings? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(projectUpdateParams: ProjectUpdateParams) = apply { - this.projectId = projectUpdateParams.projectId - this.name = projectUpdateParams.name - this.settings = projectUpdateParams.settings - additionalQueryParams(projectUpdateParams.additionalQueryParams) - additionalHeaders(projectUpdateParams.additionalHeaders) - additionalBodyProperties(projectUpdateParams.additionalBodyProperties) + projectId = projectUpdateParams.projectId + body = projectUpdateParams.body.toBuilder() + additionalHeaders = projectUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = projectUpdateParams.additionalQueryParams.toBuilder() } /** Project id */ fun projectId(projectId: String) = apply { this.projectId = projectId } /** Name of the project */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } /** * Project settings. Patch operations replace all settings, so make sure you include all * settings you want to keep. */ - fun settings(settings: ProjectSettings) = apply { this.settings = settings } + fun settings(settings: ProjectSettings?) = apply { body.settings(settings) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.settings] with `settings.orElse(null)`. */ + fun settings(settings: Optional) = settings(settings.getOrNull()) + + /** + * Sets [Builder.settings] to an arbitrary JSON value. + * + * You should usually call [Builder.settings] with a well-typed [ProjectSettings] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settings(settings: JsonField) = apply { body.settings(settings) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [ProjectUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .projectId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ProjectUpdateParams = ProjectUpdateParams( - checkNotNull(projectId) { "`projectId` is required but was not set" }, - name, - settings, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("projectId", projectId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ProjectUpdateParams && projectId == other.projectId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(projectId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ProjectUpdateParams{projectId=$projectId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Prompt.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Prompt.kt index 3805046d..aa64928b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Prompt.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Prompt.kt @@ -8,246 +8,352 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = Prompt.Builder::class) @NoAutoDetect class Prompt +@JsonCreator private constructor( - private val id: JsonField, - private val _xactId: JsonField, - private val projectId: JsonField, - private val logId: JsonField, - private val orgId: JsonField, - private val name: JsonField, - private val slug: JsonField, - private val description: JsonField, - private val created: JsonField, - private val promptData: JsonField, - private val tags: JsonField>, - private val metadata: JsonField, - private val functionType: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("_xact_id") + @ExcludeMissing + private val _xactId: JsonField = JsonMissing.of(), + @JsonProperty("log_id") @ExcludeMissing private val logId: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") @ExcludeMissing private val slug: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + private val metadata: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the prompt */ + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 transaction id of an event is unique to the network operation that processed the event * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve * a versioned snapshot of the prompt (see the `version` parameter) + * + * @throws BraintrustInvalidDataException 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 _xactId(): String = _xactId.getRequired("_xact_id") - /** Unique identifier for the project that the prompt belongs under */ - fun projectId(): String = projectId.getRequired("project_id") - - /** A literal 'p' which identifies the object as a project prompt */ + /** + * A literal 'p' which identifies the object as a project prompt + * + * @throws BraintrustInvalidDataException 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 logId(): LogId = logId.getRequired("log_id") - /** Unique identifier for the organization */ + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the organization + * + * @throws BraintrustInvalidDataException 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 orgId(): String = orgId.getRequired("org_id") - /** Name of the prompt */ - fun name(): String = name.getRequired("name") + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") - /** Unique identifier for the prompt */ + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") - /** Textual description of the prompt */ + /** + * Date of prompt creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun description(): Optional = Optional.ofNullable(description.getNullable("description")) - /** Date of prompt creation */ - fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionType(): Optional = + Optional.ofNullable(functionType.getNullable("function_type")) - /** The prompt, model, and its parameters */ + /** + * User-controlled metadata about the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun promptData(): Optional = Optional.ofNullable(promptData.getNullable("prompt_data")) - /** A list of tags for the prompt */ + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) - /** User-controlled metadata about the prompt */ - fun metadata(): Optional = Optional.ofNullable(metadata.getNullable("metadata")) - - fun functionType(): Optional = - Optional.ofNullable(functionType.getNullable("function_type")) - - /** Unique identifier for the prompt */ - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * 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 /** - * The transaction id of an event is unique to the network operation that processed the event - * insertion. Transaction ids are monotonically increasing over time and can be used to retrieve - * a versioned snapshot of the prompt (see the `version` parameter) + * Returns the raw JSON value of [_xactId]. + * + * Unlike [_xactId], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("_xact_id") @ExcludeMissing fun __xactId() = _xactId + @JsonProperty("_xact_id") @ExcludeMissing fun __xactId(): JsonField = _xactId - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId + /** + * Returns the raw JSON value of [logId]. + * + * Unlike [logId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("log_id") @ExcludeMissing fun _logId(): JsonField = logId - /** A literal 'p' which identifies the object as a project prompt */ - @JsonProperty("log_id") @ExcludeMissing fun _logId() = logId + /** + * 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 - /** Unique identifier for the organization */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId - /** Name of the prompt */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId - /** Unique identifier for the prompt */ - @JsonProperty("slug") @ExcludeMissing fun _slug() = slug + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug - /** Textual description of the prompt */ - @JsonProperty("description") @ExcludeMissing fun _description() = description + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** Date of prompt creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") @ExcludeMissing fun _promptData() = promptData + /** + * Returns the raw JSON value of [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType - /** A list of tags for the prompt */ - @JsonProperty("tags") @ExcludeMissing fun _tags() = tags + /** + * Returns the raw JSON value of [metadata]. + * + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata - /** User-controlled metadata about the prompt */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata() = metadata + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData - @JsonProperty("function_type") @ExcludeMissing fun _functionType() = functionType + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Prompt = apply { - if (!validated) { - id() - _xactId() - projectId() - logId() - orgId() - name() - slug() - description() - created() - promptData().map { it.validate() } - tags() - metadata().map { it.validate() } - functionType() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Prompt = apply { + if (validated) { + return@apply } - return other is Prompt && - this.id == other.id && - this._xactId == other._xactId && - this.projectId == other.projectId && - this.logId == other.logId && - this.orgId == other.orgId && - this.name == other.name && - this.slug == other.slug && - this.description == other.description && - this.created == other.created && - this.promptData == other.promptData && - this.tags == other.tags && - this.metadata == other.metadata && - this.functionType == other.functionType && - this.additionalProperties == other.additionalProperties + id() + _xactId() + logId() + name() + orgId() + projectId() + slug() + created() + description() + functionType() + metadata().ifPresent { it.validate() } + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - _xactId, - projectId, - logId, - orgId, - name, - slug, - description, - created, - promptData, - tags, - metadata, - functionType, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Prompt{id=$id, _xactId=$_xactId, projectId=$projectId, logId=$logId, orgId=$orgId, name=$name, slug=$slug, description=$description, created=$created, promptData=$promptData, tags=$tags, metadata=$metadata, functionType=$functionType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Prompt]. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .logId() + * .name() + * .orgId() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Prompt]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var _xactId: JsonField = JsonMissing.of() - private var projectId: JsonField = JsonMissing.of() - private var logId: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var slug: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var _xactId: JsonField? = null + private var logId: JsonField? = null + private var name: JsonField? = null + private var orgId: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null private var created: JsonField = JsonMissing.of() - private var promptData: JsonField = JsonMissing.of() - private var tags: JsonField> = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() private var functionType: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(prompt: Prompt) = apply { - this.id = prompt.id - this._xactId = prompt._xactId - this.projectId = prompt.projectId - this.logId = prompt.logId - this.orgId = prompt.orgId - this.name = prompt.name - this.slug = prompt.slug - this.description = prompt.description - this.created = prompt.created - this.promptData = prompt.promptData - this.tags = prompt.tags - this.metadata = prompt.metadata - this.functionType = prompt.functionType - additionalProperties(prompt.additionalProperties) + id = prompt.id + _xactId = prompt._xactId + logId = prompt.logId + name = prompt.name + orgId = prompt.orgId + projectId = prompt.projectId + slug = prompt.slug + created = prompt.created + description = prompt.description + functionType = prompt.functionType + metadata = prompt.metadata + promptData = prompt.promptData + tags = prompt.tags.map { it.toMutableList() } + additionalProperties = prompt.additionalProperties.toMutableMap() } /** Unique identifier for the prompt */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the prompt */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } /** * The transaction id of an event is unique to the network operation that processed the @@ -257,219 +363,351 @@ private constructor( fun _xactId(_xactId: String) = _xactId(JsonField.of(_xactId)) /** - * The transaction id of an event is unique to the network operation that processed the - * event insertion. Transaction ids are monotonically increasing over time and can be used - * to retrieve a versioned snapshot of the prompt (see the `version` parameter) + * Sets [Builder._xactId] to an arbitrary JSON value. + * + * You should usually call [Builder._xactId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - @JsonProperty("_xact_id") - @ExcludeMissing fun _xactId(_xactId: JsonField) = apply { this._xactId = _xactId } - /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - @ExcludeMissing - fun projectId(projectId: JsonField) = apply { this.projectId = projectId } - /** A literal 'p' which identifies the object as a project prompt */ fun logId(logId: LogId) = logId(JsonField.of(logId)) - /** A literal 'p' which identifies the object as a project prompt */ - @JsonProperty("log_id") - @ExcludeMissing + /** + * Sets [Builder.logId] to an arbitrary JSON value. + * + * You should usually call [Builder.logId] with a well-typed [LogId] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun logId(logId: JsonField) = apply { this.logId = logId } + /** Name of the prompt */ + 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 } + /** Unique identifier for the organization */ fun orgId(orgId: String) = orgId(JsonField.of(orgId)) - /** Unique identifier for the organization */ - @JsonProperty("org_id") - @ExcludeMissing + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - /** Name of the prompt */ - fun name(name: String) = name(JsonField.of(name)) + /** Unique identifier for the project that the prompt belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - /** Name of the prompt */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ fun slug(slug: String) = slug(JsonField.of(slug)) - /** Unique identifier for the prompt */ - @JsonProperty("slug") - @ExcludeMissing + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun slug(slug: JsonField) = apply { this.slug = slug } - /** Textual description of the prompt */ - fun description(description: String) = description(JsonField.of(description)) + /** Date of prompt creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } /** Textual description of the prompt */ - @JsonProperty("description") - @ExcludeMissing + 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 } - /** Date of prompt creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) - /** Date of prompt creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) - /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = promptData(JsonField.of(promptData)) + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { + this.functionType = functionType + } + + /** User-controlled metadata about the prompt */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) + + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) + + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - @ExcludeMissing - fun promptData(promptData: JsonField) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) - /** A list of tags for the prompt */ - fun tags(tags: List) = tags(JsonField.of(tags)) + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) - /** A list of tags for the prompt */ - @JsonProperty("tags") - @ExcludeMissing - fun tags(tags: JsonField>) = apply { this.tags = tags } + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { this.promptData = promptData } - /** User-controlled metadata about the prompt */ - fun metadata(metadata: Metadata) = metadata(JsonField.of(metadata)) + /** A list of tags for the prompt */ + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) - /** User-controlled metadata about the prompt */ - @JsonProperty("metadata") - @ExcludeMissing - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) - fun functionType(functionType: FunctionType) = functionType(JsonField.of(functionType)) + /** + * 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() } + } - @JsonProperty("function_type") - @ExcludeMissing - fun functionType(functionType: JsonField) = apply { - this.functionType = functionType + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Prompt]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ._xactId() + * .logId() + * .name() + * .orgId() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Prompt = Prompt( - id, - _xactId, - projectId, - logId, - orgId, - name, - slug, - description, + checkRequired("id", id), + checkRequired("_xactId", _xactId), + checkRequired("logId", logId), + checkRequired("name", name), + checkRequired("orgId", orgId), + checkRequired("projectId", projectId), + checkRequired("slug", slug), created, - promptData, - tags.map { it.toUnmodifiable() }, - metadata, + description, functionType, - additionalProperties.toUnmodifiable(), + metadata, + promptData, + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - class LogId - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** A literal 'p' which identifies the object as a project prompt */ + class LogId @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is LogId && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val P = LogId(JsonField.of("p")) + @JvmField val P = of("p") @JvmStatic fun of(value: String) = LogId(JsonField.of(value)) } + /** An enum containing [LogId]'s known values. */ enum class Known { - P, + P } + /** + * An enum containing [LogId]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [LogId] 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 { P, + /** An enum member indicating that [LogId] 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) { P -> Value.P 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { P -> Known.P else -> throw BraintrustInvalidDataException("Unknown LogId: $value") } - fun asString(): String = _value().asStringOrThrow() - } - - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is FunctionType && this.value == other.value + return /* spotless:off */ other is LogId && value == other.value /* spotless:on */ } override fun hashCode() = value.hashCode() override fun toString() = value.toString() + } + + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -477,14 +715,33 @@ private constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -494,6 +751,15 @@ private constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -503,79 +769,132 @@ private constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } /** User-controlled metadata about the prompt */ - @JsonDeserialize(builder = Metadata.Builder::class) @NoAutoDetect class Metadata + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metadata = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metadata = apply { + if (validated) { + return@apply } - return other is Metadata && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metadata]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metadata]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metadata: Metadata) = apply { - additionalProperties(metadata.additionalProperties) + additionalProperties = metadata.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metadata = Metadata(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metadata]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metadata && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is Prompt && id == other.id && _xactId == other._xactId && logId == other.logId && name == other.name && orgId == other.orgId && projectId == other.projectId && slug == other.slug && created == other.created && description == other.description && functionType == other.functionType && metadata == other.metadata && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, _xactId, logId, name, orgId, projectId, slug, created, description, functionType, metadata, promptData, tags, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Prompt{id=$id, _xactId=$_xactId, logId=$logId, name=$name, orgId=$orgId, projectId=$projectId, slug=$slug, created=$created, description=$description, functionType=$functionType, metadata=$metadata, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptCreateParams.kt index 5ed64365..a7e0dcef 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptCreateParams.kt @@ -5,430 +5,835 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new prompt. If there is an existing prompt in the project with the same slug as the one + * specified in the request, will return the existing prompt unmodified + */ class PromptCreateParams -constructor( - private val name: String, - private val projectId: String, - private val slug: String, - private val description: String?, - private val functionType: FunctionType?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun slug(): String = slug - - fun description(): Optional = Optional.ofNullable(description) - - fun functionType(): Optional = Optional.ofNullable(functionType) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): PromptCreateBody { - return PromptCreateBody( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = body.slug() + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionType(): Optional = body.functionType() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _slug(): JsonField = body._slug() + + /** + * 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 [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionType(): JsonField = body._functionType() + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = PromptCreateBody.Builder::class) @NoAutoDetect - class PromptCreateBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val slug: String?, - private val description: String?, - private val functionType: FunctionType?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(): String? = slug - - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description - - @JsonProperty("function_type") fun functionType(): FunctionType? = functionType - - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionType(): Optional = + Optional.ofNullable(functionType.getNullable("function_type")) + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * 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 [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is PromptCreateBody && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionType == other.functionType && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalProperties, - ) - } - return hashCode + name() + projectId() + slug() + description() + functionType() + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun toString() = - "PromptCreateBody{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalProperties=$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() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionType: FunctionType? = null - private var promptData: PromptData? = null - private var tags: List? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var functionType: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(promptCreateBody: PromptCreateBody) = apply { - this.name = promptCreateBody.name - this.projectId = promptCreateBody.projectId - this.slug = promptCreateBody.slug - this.description = promptCreateBody.description - this.functionType = promptCreateBody.functionType - this.promptData = promptCreateBody.promptData - this.tags = promptCreateBody.tags - additionalProperties(promptCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + slug = body.slug + description = body.description + functionType = body.functionType + promptData = body.promptData + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = slug(JsonField.of(slug)) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } - @JsonProperty("function_type") - fun functionType(functionType: FunctionType) = apply { + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { this.functionType = functionType } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): PromptCreateBody = - PromptCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, + 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() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("slug", slug), description, functionType, promptData, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && slug == other.slug && description == other.description && functionType == other.functionType && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is PromptCreateParams && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionType == other.functionType && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, slug, description, functionType, promptData, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "PromptCreateParams{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptCreateParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionType: FunctionType? = null - private var promptData: PromptData? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(promptCreateParams: PromptCreateParams) = apply { - this.name = promptCreateParams.name - this.projectId = promptCreateParams.projectId - this.slug = promptCreateParams.slug - this.description = promptCreateParams.description - this.functionType = promptCreateParams.functionType - this.promptData = promptCreateParams.promptData - this.tags(promptCreateParams.tags ?: listOf()) - additionalQueryParams(promptCreateParams.additionalQueryParams) - additionalHeaders(promptCreateParams.additionalHeaders) - additionalBodyProperties(promptCreateParams.additionalBodyProperties) + body = promptCreateParams.body.toBuilder() + additionalHeaders = promptCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = promptCreateParams.additionalQueryParams.toBuilder() } /** Name of the prompt */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Unique identifier for the prompt */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = apply { body.slug(slug) } - /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun slug(slug: JsonField) = apply { body.slug(slug) } - fun functionType(functionType: FunctionType) = apply { this.functionType = functionType } + /** Textual description of the prompt */ + 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) } + + fun functionType(functionType: FunctionType?) = apply { body.functionType(functionType) } + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { + body.functionType(functionType) + } /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) - } + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun tags(tags: List?) = apply { body.tags(tags) } + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + this.additionalQueryParams.putAll(additionalQueryParams) } - fun build(): PromptCreateParams = - PromptCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, - description, - functionType, - promptData, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - return other is FunctionType && this.value == other.value + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [PromptCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PromptCreateParams = + PromptCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - override fun toString() = value.toString() + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -436,14 +841,33 @@ constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -453,6 +877,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -462,6 +895,43 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "PromptCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptData.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptData.kt index 05402b44..c47b3a79 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptData.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptData.kt @@ -10,8 +10,11 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter @@ -26,2260 +29,691 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** The prompt, model, and its parameters */ -@JsonDeserialize(builder = PromptData.Builder::class) @NoAutoDetect class PromptData +@JsonCreator private constructor( - private val prompt: JsonField, - private val options: JsonField, - private val parser: JsonField, - private val toolFunctions: JsonField>, - private val origin: JsonField, - private val additionalProperties: Map, + @JsonProperty("options") + @ExcludeMissing + private val options: JsonField = JsonMissing.of(), + @JsonProperty("origin") + @ExcludeMissing + private val origin: JsonField = JsonMissing.of(), + @JsonProperty("parser") + @ExcludeMissing + private val parser: JsonField = JsonMissing.of(), + @JsonProperty("prompt") + @ExcludeMissing + private val prompt: JsonField = JsonMissing.of(), + @JsonProperty("tool_functions") + @ExcludeMissing + private val toolFunctions: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun prompt(): Optional = Optional.ofNullable(prompt.getNullable("prompt")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = Optional.ofNullable(options.getNullable("options")) - fun options(): Optional = Optional.ofNullable(options.getNullable("options")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun parser(): Optional = Optional.ofNullable(parser.getNullable("parser")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun prompt(): Optional = Optional.ofNullable(prompt.getNullable("prompt")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun toolFunctions(): Optional> = Optional.ofNullable(toolFunctions.getNullable("tool_functions")) - fun origin(): Optional = Optional.ofNullable(origin.getNullable("origin")) - - @JsonProperty("prompt") @ExcludeMissing fun _prompt() = prompt - - @JsonProperty("options") @ExcludeMissing fun _options() = options - - @JsonProperty("parser") @ExcludeMissing fun _parser() = parser - - @JsonProperty("tool_functions") @ExcludeMissing fun _toolFunctions() = toolFunctions - - @JsonProperty("origin") @ExcludeMissing fun _origin() = origin - - @JsonAnyGetter + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [origin]. + * + * Unlike [origin], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("origin") @ExcludeMissing fun _origin(): JsonField = origin + + /** + * Returns the raw JSON value of [parser]. + * + * Unlike [parser], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("parser") @ExcludeMissing fun _parser(): JsonField = parser + + /** + * Returns the raw JSON value of [prompt]. + * + * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt + + /** + * Returns the raw JSON value of [toolFunctions]. + * + * Unlike [toolFunctions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tool_functions") @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): PromptData = apply { - if (!validated) { - prompt() - options().map { it.validate() } - parser().map { it.validate() } - toolFunctions() - origin().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptData && - this.prompt == other.prompt && - this.options == other.options && - this.parser == other.parser && - this.toolFunctions == other.toolFunctions && - this.origin == other.origin && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - prompt, - options, - parser, - toolFunctions, - origin, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "PromptData{prompt=$prompt, options=$options, parser=$parser, toolFunctions=$toolFunctions, origin=$origin, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var prompt: JsonField = JsonMissing.of() - private var options: JsonField = JsonMissing.of() - private var parser: JsonField = JsonMissing.of() - private var toolFunctions: JsonField> = JsonMissing.of() - private var origin: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(promptData: PromptData) = apply { - this.prompt = promptData.prompt - this.options = promptData.options - this.parser = promptData.parser - this.toolFunctions = promptData.toolFunctions - this.origin = promptData.origin - additionalProperties(promptData.additionalProperties) - } - - fun prompt(prompt: Prompt) = prompt(JsonField.of(prompt)) - - @JsonProperty("prompt") - @ExcludeMissing - fun prompt(prompt: JsonField) = apply { this.prompt = prompt } - - fun options(options: Options) = options(JsonField.of(options)) - - @JsonProperty("options") - @ExcludeMissing - fun options(options: JsonField) = apply { this.options = options } - - fun parser(parser: Parser) = parser(JsonField.of(parser)) - - @JsonProperty("parser") - @ExcludeMissing - fun parser(parser: JsonField) = apply { this.parser = parser } - - fun toolFunctions(toolFunctions: List) = - toolFunctions(JsonField.of(toolFunctions)) - - @JsonProperty("tool_functions") - @ExcludeMissing - fun toolFunctions(toolFunctions: JsonField>) = apply { - this.toolFunctions = toolFunctions - } - - fun origin(origin: Origin) = origin(JsonField.of(origin)) - - @JsonProperty("origin") - @ExcludeMissing - fun origin(origin: JsonField) = apply { this.origin = origin } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): PromptData = - PromptData( - prompt, - options, - parser, - toolFunctions.map { it.toUnmodifiable() }, - origin, - additionalProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(builder = Options.Builder::class) - @NoAutoDetect - class Options - private constructor( - private val model: JsonField, - private val params: JsonField, - private val position: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun model(): Optional = Optional.ofNullable(model.getNullable("model")) - - fun params(): Optional = Optional.ofNullable(params.getNullable("params")) - - fun position(): Optional = Optional.ofNullable(position.getNullable("position")) - - @JsonProperty("model") @ExcludeMissing fun _model() = model - - @JsonProperty("params") @ExcludeMissing fun _params() = params - - @JsonProperty("position") @ExcludeMissing fun _position() = position - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Options = apply { - if (!validated) { - model() - params() - position() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Options && - this.model == other.model && - this.params == other.params && - this.position == other.position && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - model, - params, - position, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Options{model=$model, params=$params, position=$position, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var model: JsonField = JsonMissing.of() - private var params: JsonField = JsonMissing.of() - private var position: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(options: Options) = apply { - this.model = options.model - this.params = options.params - this.position = options.position - additionalProperties(options.additionalProperties) - } - - fun model(model: String) = model(JsonField.of(model)) - - @JsonProperty("model") - @ExcludeMissing - fun model(model: JsonField) = apply { this.model = model } - - fun params(params: Params) = params(JsonField.of(params)) - - @JsonProperty("params") - @ExcludeMissing - fun params(params: JsonField) = apply { this.params = params } - - fun position(position: String) = position(JsonField.of(position)) - - @JsonProperty("position") - @ExcludeMissing - fun position(position: JsonField) = apply { this.position = position } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Options = - Options( - model, - params, - position, - additionalProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(using = Params.Deserializer::class) - @JsonSerialize(using = Params.Serializer::class) - class Params - private constructor( - private val openaiModelParams: OpenAIModelParams? = null, - private val anthropicModelParams: AnthropicModelParams? = null, - private val googleModelParams: GoogleModelParams? = null, - private val windowAiModelParams: WindowAiModelParams? = null, - private val jsCompletionParams: JsCompletionParams? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false - - fun openaiModelParams(): Optional = - Optional.ofNullable(openaiModelParams) - - fun anthropicModelParams(): Optional = - Optional.ofNullable(anthropicModelParams) - - fun googleModelParams(): Optional = - Optional.ofNullable(googleModelParams) - - fun windowAiModelParams(): Optional = - Optional.ofNullable(windowAiModelParams) - - fun jsCompletionParams(): Optional = - Optional.ofNullable(jsCompletionParams) - - fun isOpenAIModelParams(): Boolean = openaiModelParams != null - - fun isAnthropicModelParams(): Boolean = anthropicModelParams != null - - fun isGoogleModelParams(): Boolean = googleModelParams != null - - fun isWindowAiModelParams(): Boolean = windowAiModelParams != null - - fun isJsCompletionParams(): Boolean = jsCompletionParams != null - - fun asOpenAIModelParams(): OpenAIModelParams = - openaiModelParams.getOrThrow("openaiModelParams") - - fun asAnthropicModelParams(): AnthropicModelParams = - anthropicModelParams.getOrThrow("anthropicModelParams") - - fun asGoogleModelParams(): GoogleModelParams = - googleModelParams.getOrThrow("googleModelParams") - - fun asWindowAiModelParams(): WindowAiModelParams = - windowAiModelParams.getOrThrow("windowAiModelParams") - - fun asJsCompletionParams(): JsCompletionParams = - jsCompletionParams.getOrThrow("jsCompletionParams") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T { - return when { - openaiModelParams != null -> visitor.visitOpenAIModelParams(openaiModelParams) - anthropicModelParams != null -> - visitor.visitAnthropicModelParams(anthropicModelParams) - googleModelParams != null -> visitor.visitGoogleModelParams(googleModelParams) - windowAiModelParams != null -> - visitor.visitWindowAiModelParams(windowAiModelParams) - jsCompletionParams != null -> - visitor.visitJsCompletionParams(jsCompletionParams) - else -> visitor.unknown(_json) - } - } - - fun validate(): Params = apply { - if (!validated) { - if ( - openaiModelParams == null && - anthropicModelParams == null && - googleModelParams == null && - windowAiModelParams == null && - jsCompletionParams == null - ) { - throw BraintrustInvalidDataException("Unknown Params: $_json") - } - openaiModelParams?.validate() - anthropicModelParams?.validate() - googleModelParams?.validate() - windowAiModelParams?.validate() - jsCompletionParams?.validate() - validated = true - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Params && - this.openaiModelParams == other.openaiModelParams && - this.anthropicModelParams == other.anthropicModelParams && - this.googleModelParams == other.googleModelParams && - this.windowAiModelParams == other.windowAiModelParams && - this.jsCompletionParams == other.jsCompletionParams - } - - override fun hashCode(): Int { - return Objects.hash( - openaiModelParams, - anthropicModelParams, - googleModelParams, - windowAiModelParams, - jsCompletionParams, - ) - } - - override fun toString(): String { - return when { - openaiModelParams != null -> "Params{openaiModelParams=$openaiModelParams}" - anthropicModelParams != null -> - "Params{anthropicModelParams=$anthropicModelParams}" - googleModelParams != null -> "Params{googleModelParams=$googleModelParams}" - windowAiModelParams != null -> - "Params{windowAiModelParams=$windowAiModelParams}" - jsCompletionParams != null -> "Params{jsCompletionParams=$jsCompletionParams}" - _json != null -> "Params{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Params") - } - } - - companion object { - - @JvmStatic - fun ofOpenAIModelParams(openaiModelParams: OpenAIModelParams) = - Params(openaiModelParams = openaiModelParams) - - @JvmStatic - fun ofAnthropicModelParams(anthropicModelParams: AnthropicModelParams) = - Params(anthropicModelParams = anthropicModelParams) - - @JvmStatic - fun ofGoogleModelParams(googleModelParams: GoogleModelParams) = - Params(googleModelParams = googleModelParams) - - @JvmStatic - fun ofWindowAiModelParams(windowAiModelParams: WindowAiModelParams) = - Params(windowAiModelParams = windowAiModelParams) - - @JvmStatic - fun ofJsCompletionParams(jsCompletionParams: JsCompletionParams) = - Params(jsCompletionParams = jsCompletionParams) - } - - interface Visitor { - - fun visitOpenAIModelParams(openaiModelParams: OpenAIModelParams): T - - fun visitAnthropicModelParams(anthropicModelParams: AnthropicModelParams): T - - fun visitGoogleModelParams(googleModelParams: GoogleModelParams): T - - fun visitWindowAiModelParams(windowAiModelParams: WindowAiModelParams): T - - fun visitJsCompletionParams(jsCompletionParams: JsCompletionParams): T - - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown Params: $json") - } - } - - class Deserializer : BaseDeserializer(Params::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): Params { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Params(openaiModelParams = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Params(anthropicModelParams = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Params(googleModelParams = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Params(windowAiModelParams = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Params(jsCompletionParams = it, _json = json) - } - - return Params(_json = json) - } - } - - class Serializer : BaseSerializer(Params::class) { - - override fun serialize( - value: Params, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.openaiModelParams != null -> - generator.writeObject(value.openaiModelParams) - value.anthropicModelParams != null -> - generator.writeObject(value.anthropicModelParams) - value.googleModelParams != null -> - generator.writeObject(value.googleModelParams) - value.windowAiModelParams != null -> - generator.writeObject(value.windowAiModelParams) - value.jsCompletionParams != null -> - generator.writeObject(value.jsCompletionParams) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Params") - } - } - } - - @JsonDeserialize(builder = OpenAIModelParams.Builder::class) - @NoAutoDetect - class OpenAIModelParams - private constructor( - private val useCache: JsonField, - private val temperature: JsonField, - private val topP: JsonField, - private val maxTokens: JsonField, - private val frequencyPenalty: JsonField, - private val presencePenalty: JsonField, - private val responseFormat: JsonField, - private val toolChoice: JsonField, - private val functionCall: JsonField, - private val n: JsonField, - private val stop: JsonField>, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun useCache(): Optional = - Optional.ofNullable(useCache.getNullable("use_cache")) - - fun temperature(): Optional = - Optional.ofNullable(temperature.getNullable("temperature")) - - fun topP(): Optional = Optional.ofNullable(topP.getNullable("top_p")) + fun _toolFunctions(): JsonField> = toolFunctions - fun maxTokens(): Optional = - Optional.ofNullable(maxTokens.getNullable("max_tokens")) - - fun frequencyPenalty(): Optional = - Optional.ofNullable(frequencyPenalty.getNullable("frequency_penalty")) - - fun presencePenalty(): Optional = - Optional.ofNullable(presencePenalty.getNullable("presence_penalty")) - - fun responseFormat(): Optional = - Optional.ofNullable(responseFormat.getNullable("response_format")) - - fun toolChoice(): Optional = - Optional.ofNullable(toolChoice.getNullable("tool_choice")) - - fun functionCall(): Optional = - Optional.ofNullable(functionCall.getNullable("function_call")) - - fun n(): Optional = Optional.ofNullable(n.getNullable("n")) - - fun stop(): Optional> = Optional.ofNullable(stop.getNullable("stop")) - - @JsonProperty("use_cache") @ExcludeMissing fun _useCache() = useCache - - @JsonProperty("temperature") @ExcludeMissing fun _temperature() = temperature - - @JsonProperty("top_p") @ExcludeMissing fun _topP() = topP - - @JsonProperty("max_tokens") @ExcludeMissing fun _maxTokens() = maxTokens - - @JsonProperty("frequency_penalty") - @ExcludeMissing - fun _frequencyPenalty() = frequencyPenalty - - @JsonProperty("presence_penalty") - @ExcludeMissing - fun _presencePenalty() = presencePenalty - - @JsonProperty("response_format") - @ExcludeMissing - fun _responseFormat() = responseFormat - - @JsonProperty("tool_choice") @ExcludeMissing fun _toolChoice() = toolChoice - - @JsonProperty("function_call") @ExcludeMissing fun _functionCall() = functionCall - - @JsonProperty("n") @ExcludeMissing fun _n() = n - - @JsonProperty("stop") @ExcludeMissing fun _stop() = stop - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): OpenAIModelParams = apply { - if (!validated) { - useCache() - temperature() - topP() - maxTokens() - frequencyPenalty() - presencePenalty() - responseFormat().map { it.validate() } - toolChoice() - functionCall() - n() - stop() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is OpenAIModelParams && - this.useCache == other.useCache && - this.temperature == other.temperature && - this.topP == other.topP && - this.maxTokens == other.maxTokens && - this.frequencyPenalty == other.frequencyPenalty && - this.presencePenalty == other.presencePenalty && - this.responseFormat == other.responseFormat && - this.toolChoice == other.toolChoice && - this.functionCall == other.functionCall && - this.n == other.n && - this.stop == other.stop && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - useCache, - temperature, - topP, - maxTokens, - frequencyPenalty, - presencePenalty, - responseFormat, - toolChoice, - functionCall, - n, - stop, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "OpenAIModelParams{useCache=$useCache, temperature=$temperature, topP=$topP, maxTokens=$maxTokens, frequencyPenalty=$frequencyPenalty, presencePenalty=$presencePenalty, responseFormat=$responseFormat, toolChoice=$toolChoice, functionCall=$functionCall, n=$n, stop=$stop, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var useCache: JsonField = JsonMissing.of() - private var temperature: JsonField = JsonMissing.of() - private var topP: JsonField = JsonMissing.of() - private var maxTokens: JsonField = JsonMissing.of() - private var frequencyPenalty: JsonField = JsonMissing.of() - private var presencePenalty: JsonField = JsonMissing.of() - private var responseFormat: JsonField = JsonMissing.of() - private var toolChoice: JsonField = JsonMissing.of() - private var functionCall: JsonField = JsonMissing.of() - private var n: JsonField = JsonMissing.of() - private var stop: JsonField> = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(openaiModelParams: OpenAIModelParams) = apply { - this.useCache = openaiModelParams.useCache - this.temperature = openaiModelParams.temperature - this.topP = openaiModelParams.topP - this.maxTokens = openaiModelParams.maxTokens - this.frequencyPenalty = openaiModelParams.frequencyPenalty - this.presencePenalty = openaiModelParams.presencePenalty - this.responseFormat = openaiModelParams.responseFormat - this.toolChoice = openaiModelParams.toolChoice - this.functionCall = openaiModelParams.functionCall - this.n = openaiModelParams.n - this.stop = openaiModelParams.stop - additionalProperties(openaiModelParams.additionalProperties) - } - - fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) - - @JsonProperty("use_cache") - @ExcludeMissing - fun useCache(useCache: JsonField) = apply { this.useCache = useCache } - - fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) - - @JsonProperty("temperature") - @ExcludeMissing - fun temperature(temperature: JsonField) = apply { - this.temperature = temperature - } - - fun topP(topP: Double) = topP(JsonField.of(topP)) - - @JsonProperty("top_p") - @ExcludeMissing - fun topP(topP: JsonField) = apply { this.topP = topP } - - fun maxTokens(maxTokens: Double) = maxTokens(JsonField.of(maxTokens)) - - @JsonProperty("max_tokens") - @ExcludeMissing - fun maxTokens(maxTokens: JsonField) = apply { - this.maxTokens = maxTokens - } - - fun frequencyPenalty(frequencyPenalty: Double) = - frequencyPenalty(JsonField.of(frequencyPenalty)) - - @JsonProperty("frequency_penalty") - @ExcludeMissing - fun frequencyPenalty(frequencyPenalty: JsonField) = apply { - this.frequencyPenalty = frequencyPenalty - } - - fun presencePenalty(presencePenalty: Double) = - presencePenalty(JsonField.of(presencePenalty)) - - @JsonProperty("presence_penalty") - @ExcludeMissing - fun presencePenalty(presencePenalty: JsonField) = apply { - this.presencePenalty = presencePenalty - } - - fun responseFormat(responseFormat: ResponseFormat) = - responseFormat(JsonField.of(responseFormat)) - - @JsonProperty("response_format") - @ExcludeMissing - fun responseFormat(responseFormat: JsonField) = apply { - this.responseFormat = responseFormat - } - - fun toolChoice(toolChoice: ToolChoice) = toolChoice(JsonField.of(toolChoice)) - - @JsonProperty("tool_choice") - @ExcludeMissing - fun toolChoice(toolChoice: JsonField) = apply { - this.toolChoice = toolChoice - } - - fun functionCall(functionCall: FunctionCall) = - functionCall(JsonField.of(functionCall)) - - @JsonProperty("function_call") - @ExcludeMissing - fun functionCall(functionCall: JsonField) = apply { - this.functionCall = functionCall - } - - fun n(n: Double) = n(JsonField.of(n)) - - @JsonProperty("n") - @ExcludeMissing - fun n(n: JsonField) = apply { this.n = n } - - fun stop(stop: List) = stop(JsonField.of(stop)) - - @JsonProperty("stop") - @ExcludeMissing - fun stop(stop: JsonField>) = apply { this.stop = stop } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): OpenAIModelParams = - OpenAIModelParams( - useCache, - temperature, - topP, - maxTokens, - frequencyPenalty, - presencePenalty, - responseFormat, - toolChoice, - functionCall, - n, - stop.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), - ) - } - - @JsonDeserialize(using = FunctionCall.Deserializer::class) - @JsonSerialize(using = FunctionCall.Serializer::class) - class FunctionCall - private constructor( - private val auto: Auto? = null, - private val none: None? = null, - private val function: Function? = null, - private val _json: JsonValue? = null, - ) { - - private var validated: Boolean = false - - fun auto(): Optional = Optional.ofNullable(auto) - - fun none(): Optional = Optional.ofNullable(none) - - fun function(): Optional = Optional.ofNullable(function) - - fun isAuto(): Boolean = auto != null - - fun isNone(): Boolean = none != null - - fun isFunction(): Boolean = function != null - - fun asAuto(): Auto = auto.getOrThrow("auto") - - fun asNone(): None = none.getOrThrow("none") - - fun asFunction(): Function = function.getOrThrow("function") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T { - return when { - auto != null -> visitor.visitAuto(auto) - none != null -> visitor.visitNone(none) - function != null -> visitor.visitFunction(function) - else -> visitor.unknown(_json) - } - } - - fun validate(): FunctionCall = apply { - if (!validated) { - if (auto == null && none == null && function == null) { - throw BraintrustInvalidDataException("Unknown FunctionCall: $_json") - } - function?.validate() - validated = true - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is FunctionCall && - this.auto == other.auto && - this.none == other.none && - this.function == other.function - } - - override fun hashCode(): Int { - return Objects.hash( - auto, - none, - function, - ) - } - - override fun toString(): String { - return when { - auto != null -> "FunctionCall{auto=$auto}" - none != null -> "FunctionCall{none=$none}" - function != null -> "FunctionCall{function=$function}" - _json != null -> "FunctionCall{_unknown=$_json}" - else -> throw IllegalStateException("Invalid FunctionCall") - } - } - - companion object { - - @JvmStatic fun ofAuto(auto: Auto) = FunctionCall(auto = auto) - - @JvmStatic fun ofNone(none: None) = FunctionCall(none = none) - - @JvmStatic - fun ofFunction(function: Function) = FunctionCall(function = function) - } - - interface Visitor { - - fun visitAuto(auto: Auto): T - - fun visitNone(none: None): T - - fun visitFunction(function: Function): T - - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown FunctionCall: $json") - } - } - - class Deserializer : BaseDeserializer(FunctionCall::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): FunctionCall { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return FunctionCall(auto = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef())?.let { - return FunctionCall(none = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return FunctionCall(function = it, _json = json) - } - - return FunctionCall(_json = json) - } - } - - class Serializer : BaseSerializer(FunctionCall::class) { - - override fun serialize( - value: FunctionCall, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.none != null -> generator.writeObject(value.none) - value.function != null -> generator.writeObject(value.function) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid FunctionCall") - } - } - } - - class Auto - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Auto && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val AUTO = Auto(JsonField.of("auto")) - - @JvmStatic fun of(value: String) = Auto(JsonField.of(value)) - } - - enum class Known { - AUTO, - } - - enum class Value { - AUTO, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - AUTO -> Value.AUTO - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - AUTO -> Known.AUTO - else -> throw BraintrustInvalidDataException("Unknown Auto: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class None - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is None && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val NONE = None(JsonField.of("none")) - - @JvmStatic fun of(value: String) = None(JsonField.of(value)) - } - - enum class Known { - NONE, - } - - enum class Value { - NONE, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - NONE -> Value.NONE - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - NONE -> Known.NONE - else -> throw BraintrustInvalidDataException("Unknown None: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - @JsonDeserialize(builder = Function.Builder::class) - @NoAutoDetect - class Function - private constructor( - private val name: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun name(): String = name.getRequired("name") - - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Function = apply { - if (!validated) { - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Function && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(name, additionalProperties) - } - return hashCode - } - - override fun toString() = - "Function{name=$name, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var name: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(function: Function) = apply { - this.name = function.name - additionalProperties(function.additionalProperties) - } - - fun name(name: String) = name(JsonField.of(name)) - - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun build(): Function = - Function(name, additionalProperties.toUnmodifiable()) - } - } - } - - @JsonDeserialize(builder = ResponseFormat.Builder::class) - @NoAutoDetect - class ResponseFormat - private constructor( - private val type: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): ResponseFormat = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ResponseFormat && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode - } - - override fun toString() = - "ResponseFormat{type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = - mutableMapOf() - - @JvmSynthetic - internal fun from(responseFormat: ResponseFormat) = apply { - this.type = responseFormat.type - additionalProperties(responseFormat.additionalProperties) - } - - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties( - additionalProperties: Map - ) = apply { this.additionalProperties.putAll(additionalProperties) } - - fun build(): ResponseFormat = - ResponseFormat(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val JSON_OBJECT = Type(JsonField.of("json_object")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - JSON_OBJECT, - } - - enum class Value { - JSON_OBJECT, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - JSON_OBJECT -> Value.JSON_OBJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - JSON_OBJECT -> Known.JSON_OBJECT - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } - } - - @JsonDeserialize(builder = AnthropicModelParams.Builder::class) - @NoAutoDetect - class AnthropicModelParams - private constructor( - private val useCache: JsonField, - private val maxTokens: JsonField, - private val temperature: JsonField, - private val topP: JsonField, - private val topK: JsonField, - private val stopSequences: JsonField>, - private val maxTokensToSample: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun useCache(): Optional = - Optional.ofNullable(useCache.getNullable("use_cache")) - - fun maxTokens(): Double = maxTokens.getRequired("max_tokens") - - fun temperature(): Double = temperature.getRequired("temperature") - - fun topP(): Optional = Optional.ofNullable(topP.getNullable("top_p")) - - fun topK(): Optional = Optional.ofNullable(topK.getNullable("top_k")) - - fun stopSequences(): Optional> = - Optional.ofNullable(stopSequences.getNullable("stop_sequences")) - - /** This is a legacy parameter that should not be used. */ - fun maxTokensToSample(): Optional = - Optional.ofNullable(maxTokensToSample.getNullable("max_tokens_to_sample")) - - @JsonProperty("use_cache") @ExcludeMissing fun _useCache() = useCache - - @JsonProperty("max_tokens") @ExcludeMissing fun _maxTokens() = maxTokens - - @JsonProperty("temperature") @ExcludeMissing fun _temperature() = temperature - - @JsonProperty("top_p") @ExcludeMissing fun _topP() = topP - - @JsonProperty("top_k") @ExcludeMissing fun _topK() = topK - - @JsonProperty("stop_sequences") @ExcludeMissing fun _stopSequences() = stopSequences - - /** This is a legacy parameter that should not be used. */ - @JsonProperty("max_tokens_to_sample") - @ExcludeMissing - fun _maxTokensToSample() = maxTokensToSample - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): AnthropicModelParams = apply { - if (!validated) { - useCache() - maxTokens() - temperature() - topP() - topK() - stopSequences() - maxTokensToSample() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AnthropicModelParams && - this.useCache == other.useCache && - this.maxTokens == other.maxTokens && - this.temperature == other.temperature && - this.topP == other.topP && - this.topK == other.topK && - this.stopSequences == other.stopSequences && - this.maxTokensToSample == other.maxTokensToSample && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - useCache, - maxTokens, - temperature, - topP, - topK, - stopSequences, - maxTokensToSample, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AnthropicModelParams{useCache=$useCache, maxTokens=$maxTokens, temperature=$temperature, topP=$topP, topK=$topK, stopSequences=$stopSequences, maxTokensToSample=$maxTokensToSample, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var useCache: JsonField = JsonMissing.of() - private var maxTokens: JsonField = JsonMissing.of() - private var temperature: JsonField = JsonMissing.of() - private var topP: JsonField = JsonMissing.of() - private var topK: JsonField = JsonMissing.of() - private var stopSequences: JsonField> = JsonMissing.of() - private var maxTokensToSample: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(anthropicModelParams: AnthropicModelParams) = apply { - this.useCache = anthropicModelParams.useCache - this.maxTokens = anthropicModelParams.maxTokens - this.temperature = anthropicModelParams.temperature - this.topP = anthropicModelParams.topP - this.topK = anthropicModelParams.topK - this.stopSequences = anthropicModelParams.stopSequences - this.maxTokensToSample = anthropicModelParams.maxTokensToSample - additionalProperties(anthropicModelParams.additionalProperties) - } - - fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) - - @JsonProperty("use_cache") - @ExcludeMissing - fun useCache(useCache: JsonField) = apply { this.useCache = useCache } - - fun maxTokens(maxTokens: Double) = maxTokens(JsonField.of(maxTokens)) - - @JsonProperty("max_tokens") - @ExcludeMissing - fun maxTokens(maxTokens: JsonField) = apply { - this.maxTokens = maxTokens - } - - fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) - - @JsonProperty("temperature") - @ExcludeMissing - fun temperature(temperature: JsonField) = apply { - this.temperature = temperature - } - - fun topP(topP: Double) = topP(JsonField.of(topP)) - - @JsonProperty("top_p") - @ExcludeMissing - fun topP(topP: JsonField) = apply { this.topP = topP } - - fun topK(topK: Double) = topK(JsonField.of(topK)) - - @JsonProperty("top_k") - @ExcludeMissing - fun topK(topK: JsonField) = apply { this.topK = topK } - - fun stopSequences(stopSequences: List) = - stopSequences(JsonField.of(stopSequences)) - - @JsonProperty("stop_sequences") - @ExcludeMissing - fun stopSequences(stopSequences: JsonField>) = apply { - this.stopSequences = stopSequences - } - - /** This is a legacy parameter that should not be used. */ - fun maxTokensToSample(maxTokensToSample: Double) = - maxTokensToSample(JsonField.of(maxTokensToSample)) - - /** This is a legacy parameter that should not be used. */ - @JsonProperty("max_tokens_to_sample") - @ExcludeMissing - fun maxTokensToSample(maxTokensToSample: JsonField) = apply { - this.maxTokensToSample = maxTokensToSample - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): AnthropicModelParams = - AnthropicModelParams( - useCache, - maxTokens, - temperature, - topP, - topK, - stopSequences.map { it.toUnmodifiable() }, - maxTokensToSample, - additionalProperties.toUnmodifiable(), - ) - } - } - - @JsonDeserialize(builder = GoogleModelParams.Builder::class) - @NoAutoDetect - class GoogleModelParams - private constructor( - private val useCache: JsonField, - private val temperature: JsonField, - private val maxOutputTokens: JsonField, - private val topP: JsonField, - private val topK: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun useCache(): Optional = - Optional.ofNullable(useCache.getNullable("use_cache")) - - fun temperature(): Optional = - Optional.ofNullable(temperature.getNullable("temperature")) - - fun maxOutputTokens(): Optional = - Optional.ofNullable(maxOutputTokens.getNullable("maxOutputTokens")) - - fun topP(): Optional = Optional.ofNullable(topP.getNullable("topP")) - - fun topK(): Optional = Optional.ofNullable(topK.getNullable("topK")) - - @JsonProperty("use_cache") @ExcludeMissing fun _useCache() = useCache - - @JsonProperty("temperature") @ExcludeMissing fun _temperature() = temperature - - @JsonProperty("maxOutputTokens") - @ExcludeMissing - fun _maxOutputTokens() = maxOutputTokens - - @JsonProperty("topP") @ExcludeMissing fun _topP() = topP - - @JsonProperty("topK") @ExcludeMissing fun _topK() = topK - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): GoogleModelParams = apply { - if (!validated) { - useCache() - temperature() - maxOutputTokens() - topP() - topK() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is GoogleModelParams && - this.useCache == other.useCache && - this.temperature == other.temperature && - this.maxOutputTokens == other.maxOutputTokens && - this.topP == other.topP && - this.topK == other.topK && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - useCache, - temperature, - maxOutputTokens, - topP, - topK, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "GoogleModelParams{useCache=$useCache, temperature=$temperature, maxOutputTokens=$maxOutputTokens, topP=$topP, topK=$topK, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var useCache: JsonField = JsonMissing.of() - private var temperature: JsonField = JsonMissing.of() - private var maxOutputTokens: JsonField = JsonMissing.of() - private var topP: JsonField = JsonMissing.of() - private var topK: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(googleModelParams: GoogleModelParams) = apply { - this.useCache = googleModelParams.useCache - this.temperature = googleModelParams.temperature - this.maxOutputTokens = googleModelParams.maxOutputTokens - this.topP = googleModelParams.topP - this.topK = googleModelParams.topK - additionalProperties(googleModelParams.additionalProperties) - } - - fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) - - @JsonProperty("use_cache") - @ExcludeMissing - fun useCache(useCache: JsonField) = apply { this.useCache = useCache } - - fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) - - @JsonProperty("temperature") - @ExcludeMissing - fun temperature(temperature: JsonField) = apply { - this.temperature = temperature - } - - fun maxOutputTokens(maxOutputTokens: Double) = - maxOutputTokens(JsonField.of(maxOutputTokens)) - - @JsonProperty("maxOutputTokens") - @ExcludeMissing - fun maxOutputTokens(maxOutputTokens: JsonField) = apply { - this.maxOutputTokens = maxOutputTokens - } - - fun topP(topP: Double) = topP(JsonField.of(topP)) - - @JsonProperty("topP") - @ExcludeMissing - fun topP(topP: JsonField) = apply { this.topP = topP } - - fun topK(topK: Double) = topK(JsonField.of(topK)) - - @JsonProperty("topK") - @ExcludeMissing - fun topK(topK: JsonField) = apply { this.topK = topK } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): GoogleModelParams = - GoogleModelParams( - useCache, - temperature, - maxOutputTokens, - topP, - topK, - additionalProperties.toUnmodifiable(), - ) - } - } - - @JsonDeserialize(builder = WindowAiModelParams.Builder::class) - @NoAutoDetect - class WindowAiModelParams - private constructor( - private val useCache: JsonField, - private val temperature: JsonField, - private val topK: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun useCache(): Optional = - Optional.ofNullable(useCache.getNullable("use_cache")) - - fun temperature(): Optional = - Optional.ofNullable(temperature.getNullable("temperature")) - - fun topK(): Optional = Optional.ofNullable(topK.getNullable("topK")) - - @JsonProperty("use_cache") @ExcludeMissing fun _useCache() = useCache - - @JsonProperty("temperature") @ExcludeMissing fun _temperature() = temperature - - @JsonProperty("topK") @ExcludeMissing fun _topK() = topK - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): WindowAiModelParams = apply { - if (!validated) { - useCache() - temperature() - topK() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is WindowAiModelParams && - this.useCache == other.useCache && - this.temperature == other.temperature && - this.topK == other.topK && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - useCache, - temperature, - topK, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "WindowAiModelParams{useCache=$useCache, temperature=$temperature, topK=$topK, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - class Builder { + private var validated: Boolean = false - private var useCache: JsonField = JsonMissing.of() - private var temperature: JsonField = JsonMissing.of() - private var topK: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + fun validate(): PromptData = apply { + if (validated) { + return@apply + } - @JvmSynthetic - internal fun from(windowAiModelParams: WindowAiModelParams) = apply { - this.useCache = windowAiModelParams.useCache - this.temperature = windowAiModelParams.temperature - this.topK = windowAiModelParams.topK - additionalProperties(windowAiModelParams.additionalProperties) - } + options().ifPresent { it.validate() } + origin().ifPresent { it.validate() } + parser().ifPresent { it.validate() } + prompt().ifPresent { it.validate() } + toolFunctions().ifPresent { it.forEach { it.validate() } } + validated = true + } - fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + fun toBuilder() = Builder().from(this) - @JsonProperty("use_cache") - @ExcludeMissing - fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + companion object { - fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + /** Returns a mutable builder for constructing an instance of [PromptData]. */ + @JvmStatic fun builder() = Builder() + } - @JsonProperty("temperature") - @ExcludeMissing - fun temperature(temperature: JsonField) = apply { - this.temperature = temperature - } + /** A builder for [PromptData]. */ + class Builder internal constructor() { - fun topK(topK: Double) = topK(JsonField.of(topK)) + private var options: JsonField = JsonMissing.of() + private var origin: JsonField = JsonMissing.of() + private var parser: JsonField = JsonMissing.of() + private var prompt: JsonField = JsonMissing.of() + private var toolFunctions: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() - @JsonProperty("topK") - @ExcludeMissing - fun topK(topK: JsonField) = apply { this.topK = topK } + @JvmSynthetic + internal fun from(promptData: PromptData) = apply { + options = promptData.options + origin = promptData.origin + parser = promptData.parser + prompt = promptData.prompt + toolFunctions = promptData.toolFunctions.map { it.toMutableList() } + additionalProperties = promptData.additionalProperties.toMutableMap() + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + fun options(options: PromptOptions?) = options(JsonField.ofNullable(options)) - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [PromptOptions] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } - fun build(): WindowAiModelParams = - WindowAiModelParams( - useCache, - temperature, - topK, - additionalProperties.toUnmodifiable(), - ) - } - } + fun origin(origin: Origin?) = origin(JsonField.ofNullable(origin)) - @JsonDeserialize(builder = JsCompletionParams.Builder::class) - @NoAutoDetect - class JsCompletionParams - private constructor( - private val useCache: JsonField, - private val additionalProperties: Map, - ) { + /** Alias for calling [Builder.origin] with `origin.orElse(null)`. */ + fun origin(origin: Optional) = origin(origin.getOrNull()) - private var validated: Boolean = false + /** + * Sets [Builder.origin] to an arbitrary JSON value. + * + * You should usually call [Builder.origin] with a well-typed [Origin] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun origin(origin: JsonField) = apply { this.origin = origin } - private var hashCode: Int = 0 + fun parser(parser: Parser?) = parser(JsonField.ofNullable(parser)) - fun useCache(): Optional = - Optional.ofNullable(useCache.getNullable("use_cache")) + /** Alias for calling [Builder.parser] with `parser.orElse(null)`. */ + fun parser(parser: Optional) = parser(parser.getOrNull()) - @JsonProperty("use_cache") @ExcludeMissing fun _useCache() = useCache + /** + * Sets [Builder.parser] to an arbitrary JSON value. + * + * You should usually call [Builder.parser] with a well-typed [Parser] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun parser(parser: JsonField) = apply { this.parser = parser } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun prompt(prompt: Prompt?) = prompt(JsonField.ofNullable(prompt)) - fun validate(): JsCompletionParams = apply { - if (!validated) { - useCache() - validated = true - } - } + /** Alias for calling [Builder.prompt] with `prompt.orElse(null)`. */ + fun prompt(prompt: Optional) = prompt(prompt.getOrNull()) - fun toBuilder() = Builder().from(this) + /** + * Sets [Builder.prompt] to an arbitrary JSON value. + * + * You should usually call [Builder.prompt] with a well-typed [Prompt] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun prompt(prompt: JsonField) = apply { this.prompt = prompt } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Alias for calling [prompt] with `Prompt.ofCompletion(completion)`. */ + fun prompt(completion: Prompt.Completion) = prompt(Prompt.ofCompletion(completion)) - return other is JsCompletionParams && - this.useCache == other.useCache && - this.additionalProperties == other.additionalProperties - } + /** Alias for calling [prompt] with `Prompt.ofChat(chat)`. */ + fun prompt(chat: Prompt.Chat) = prompt(Prompt.ofChat(chat)) - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(useCache, additionalProperties) - } - return hashCode - } + fun toolFunctions(toolFunctions: List?) = + toolFunctions(JsonField.ofNullable(toolFunctions)) - override fun toString() = - "JsCompletionParams{useCache=$useCache, additionalProperties=$additionalProperties}" + /** Alias for calling [Builder.toolFunctions] with `toolFunctions.orElse(null)`. */ + fun toolFunctions(toolFunctions: Optional>) = + toolFunctions(toolFunctions.getOrNull()) - companion object { + /** + * Sets [Builder.toolFunctions] to an arbitrary JSON value. + * + * You should usually call [Builder.toolFunctions] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun toolFunctions(toolFunctions: JsonField>) = apply { + this.toolFunctions = toolFunctions.map { it.toMutableList() } + } - @JvmStatic fun builder() = Builder() + /** + * Adds a single [ToolFunction] to [toolFunctions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addToolFunction(toolFunction: ToolFunction) = apply { + toolFunctions = + (toolFunctions ?: JsonField.of(mutableListOf())).also { + checkKnown("toolFunctions", it).add(toolFunction) } + } - class Builder { - - private var useCache: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(jsCompletionParams: JsCompletionParams) = apply { - this.useCache = jsCompletionParams.useCache - additionalProperties(jsCompletionParams.additionalProperties) - } + /** Alias for calling [addToolFunction] with `ToolFunction.ofFunction(function)`. */ + fun addToolFunction(function: ToolFunction.Function) = + addToolFunction(ToolFunction.ofFunction(function)) - fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + /** Alias for calling [addToolFunction] with `ToolFunction.ofGlobal(global)`. */ + fun addToolFunction(global: ToolFunction.Global) = + addToolFunction(ToolFunction.ofGlobal(global)) - @JsonProperty("use_cache") - @ExcludeMissing - fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun build(): JsCompletionParams = - JsCompletionParams(useCache, additionalProperties.toUnmodifiable()) - } - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } + + /** + * Returns an immutable instance of [PromptData]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PromptData = + PromptData( + options, + origin, + parser, + prompt, + (toolFunctions ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), + ) } - @JsonDeserialize(builder = Origin.Builder::class) @NoAutoDetect class Origin + @JsonCreator private constructor( - private val promptId: JsonField, - private val projectId: JsonField, - private val promptVersion: JsonField, - private val additionalProperties: Map, + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("prompt_id") + @ExcludeMissing + private val promptId: JsonField = JsonMissing.of(), + @JsonProperty("prompt_version") + @ExcludeMissing + private val promptVersion: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun projectId(): Optional = Optional.ofNullable(projectId.getNullable("project_id")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun promptId(): Optional = Optional.ofNullable(promptId.getNullable("prompt_id")) - fun projectId(): Optional = Optional.ofNullable(projectId.getNullable("project_id")) - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ fun promptVersion(): Optional = Optional.ofNullable(promptVersion.getNullable("prompt_version")) - @JsonProperty("prompt_id") @ExcludeMissing fun _promptId() = promptId - - @JsonProperty("project_id") @ExcludeMissing fun _projectId() = projectId - - @JsonProperty("prompt_version") @ExcludeMissing fun _promptVersion() = promptVersion + /** + * Returns the raw JSON value of [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [promptId]. + * + * Unlike [promptId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_id") @ExcludeMissing fun _promptId(): JsonField = promptId + + /** + * Returns the raw JSON value of [promptVersion]. + * + * Unlike [promptVersion], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("prompt_version") + @ExcludeMissing + fun _promptVersion(): JsonField = promptVersion @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Origin = apply { - if (!validated) { - promptId() - projectId() - promptVersion() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Origin = apply { + if (validated) { + return@apply } - return other is Origin && - this.promptId == other.promptId && - this.projectId == other.projectId && - this.promptVersion == other.promptVersion && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - promptId, - projectId, - promptVersion, - additionalProperties, - ) - } - return hashCode + projectId() + promptId() + promptVersion() + validated = true } - override fun toString() = - "Origin{promptId=$promptId, projectId=$projectId, promptVersion=$promptVersion, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Origin]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Origin]. */ + class Builder internal constructor() { - private var promptId: JsonField = JsonMissing.of() private var projectId: JsonField = JsonMissing.of() + private var promptId: JsonField = JsonMissing.of() private var promptVersion: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(origin: Origin) = apply { - this.promptId = origin.promptId - this.projectId = origin.projectId - this.promptVersion = origin.promptVersion - additionalProperties(origin.additionalProperties) + projectId = origin.projectId + promptId = origin.promptId + promptVersion = origin.promptVersion + additionalProperties = origin.additionalProperties.toMutableMap() } - fun promptId(promptId: String) = promptId(JsonField.of(promptId)) - - @JsonProperty("prompt_id") - @ExcludeMissing - fun promptId(promptId: JsonField) = apply { this.promptId = promptId } - fun projectId(projectId: String) = projectId(JsonField.of(projectId)) - @JsonProperty("project_id") - @ExcludeMissing + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + fun promptId(promptId: String) = promptId(JsonField.of(promptId)) + + /** + * Sets [Builder.promptId] to an arbitrary JSON value. + * + * You should usually call [Builder.promptId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptId(promptId: JsonField) = apply { this.promptId = promptId } + fun promptVersion(promptVersion: String) = promptVersion(JsonField.of(promptVersion)) - @JsonProperty("prompt_version") - @ExcludeMissing + /** + * Sets [Builder.promptVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.promptVersion] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun promptVersion(promptVersion: JsonField) = apply { this.promptVersion = promptVersion } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Origin]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): Origin = - Origin( - promptId, - projectId, - promptVersion, - additionalProperties.toUnmodifiable(), - ) + Origin(projectId, promptId, promptVersion, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Origin && projectId == other.projectId && promptId == other.promptId && promptVersion == other.promptVersion && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(projectId, promptId, promptVersion, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Origin{projectId=$projectId, promptId=$promptId, promptVersion=$promptVersion, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Parser.Builder::class) @NoAutoDetect class Parser + @JsonCreator private constructor( - private val type: JsonField, - private val useCot: JsonField, - private val choiceScores: JsonField, - private val additionalProperties: Map, + @JsonProperty("choice_scores") + @ExcludeMissing + private val choiceScores: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonProperty("use_cot") + @ExcludeMissing + private val useCot: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 choiceScores(): ChoiceScores = choiceScores.getRequired("choice_scores") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + /** + * @throws BraintrustInvalidDataException 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 useCot(): Boolean = useCot.getRequired("use_cot") - fun choiceScores(): ChoiceScores = choiceScores.getRequired("choice_scores") - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("use_cot") @ExcludeMissing fun _useCot() = useCot - - @JsonProperty("choice_scores") @ExcludeMissing fun _choiceScores() = choiceScores + /** + * Returns the raw JSON value of [choiceScores]. + * + * Unlike [choiceScores], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("choice_scores") + @ExcludeMissing + fun _choiceScores(): JsonField = choiceScores + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [useCot]. + * + * Unlike [useCot], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("use_cot") @ExcludeMissing fun _useCot(): JsonField = useCot @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Parser = apply { - if (!validated) { - type() - useCot() - choiceScores().validate() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Parser = apply { + if (validated) { + return@apply } - return other is Parser && - this.type == other.type && - this.useCot == other.useCot && - this.choiceScores == other.choiceScores && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - useCot, - choiceScores, - additionalProperties, - ) - } - return hashCode + choiceScores().validate() + type() + useCot() + validated = true } - override fun toString() = - "Parser{type=$type, useCot=$useCot, choiceScores=$choiceScores, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Parser]. + * + * The following fields are required: + * ```java + * .choiceScores() + * .type() + * .useCot() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Parser]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var useCot: JsonField = JsonMissing.of() - private var choiceScores: JsonField = JsonMissing.of() + private var choiceScores: JsonField? = null + private var type: JsonField? = null + private var useCot: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(parser: Parser) = apply { - this.type = parser.type - this.useCot = parser.useCot - this.choiceScores = parser.choiceScores - additionalProperties(parser.additionalProperties) + choiceScores = parser.choiceScores + type = parser.type + useCot = parser.useCot + additionalProperties = parser.additionalProperties.toMutableMap() + } + + fun choiceScores(choiceScores: ChoiceScores) = choiceScores(JsonField.of(choiceScores)) + + /** + * Sets [Builder.choiceScores] to an arbitrary JSON value. + * + * You should usually call [Builder.choiceScores] with a well-typed [ChoiceScores] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun choiceScores(choiceScores: JsonField) = apply { + this.choiceScores = choiceScores } fun type(type: Type) = type(JsonField.of(type)) - @JsonProperty("type") - @ExcludeMissing + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun type(type: JsonField) = apply { this.type = type } fun useCot(useCot: Boolean) = useCot(JsonField.of(useCot)) - @JsonProperty("use_cot") - @ExcludeMissing + /** + * Sets [Builder.useCot] to an arbitrary JSON value. + * + * You should usually call [Builder.useCot] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun useCot(useCot: JsonField) = apply { this.useCot = useCot } - fun choiceScores(choiceScores: ChoiceScores) = choiceScores(JsonField.of(choiceScores)) - - @JsonProperty("choice_scores") - @ExcludeMissing - fun choiceScores(choiceScores: JsonField) = apply { - this.choiceScores = choiceScores - } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Parser]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .choiceScores() + * .type() + * .useCot() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Parser = Parser( - type, - useCot, - choiceScores, - additionalProperties.toUnmodifiable(), + checkRequired("choiceScores", choiceScores), + checkRequired("type", type), + checkRequired("useCot", useCot), + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = ChoiceScores.Builder::class) @NoAutoDetect class ChoiceScores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ChoiceScores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ChoiceScores = apply { + if (validated) { + return@apply } - return other is ChoiceScores && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "ChoiceScores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ChoiceScores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ChoiceScores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(choiceScores: ChoiceScores) = apply { - additionalProperties(choiceScores.additionalProperties) + additionalProperties = choiceScores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2287,60 +721,149 @@ private constructor( this.additionalProperties.putAll(additionalProperties) } - fun build(): ChoiceScores = ChoiceScores(additionalProperties.toUnmodifiable()) - } - } + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Returns an immutable instance of [ChoiceScores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ChoiceScores = ChoiceScores(additionalProperties.toImmutable()) + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Type && this.value == other.value + return /* spotless:off */ other is ChoiceScores && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode() = value.hashCode() + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ - override fun toString() = value.toString() + override fun hashCode(): Int = hashCode + + override fun toString() = "ChoiceScores{additionalProperties=$additionalProperties}" + } + + class Type @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 LLM_CLASSIFIER = Type(JsonField.of("llm_classifier")) + @JvmField val LLM_CLASSIFIER = of("llm_classifier") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - LLM_CLASSIFIER, + LLM_CLASSIFIER } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { LLM_CLASSIFIER, + /** An enum member indicating that [Type] 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) { LLM_CLASSIFIER -> Value.LLM_CLASSIFIER 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { LLM_CLASSIFIER -> Known.LLM_CLASSIFIER else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Parser && choiceScores == other.choiceScores && type == other.type && useCot == other.useCot && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(choiceScores, type, useCot, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Parser{choiceScores=$choiceScores, type=$type, useCot=$useCot, additionalProperties=$additionalProperties}" } @JsonDeserialize(using = Prompt.Deserializer::class) @@ -2349,51 +872,50 @@ private constructor( private constructor( private val completion: Completion? = null, private val chat: Chat? = null, - private val nullableVariant: NullableVariant? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun completion(): Optional = Optional.ofNullable(completion) fun chat(): Optional = Optional.ofNullable(chat) - fun nullableVariant(): Optional = Optional.ofNullable(nullableVariant) - fun isCompletion(): Boolean = completion != null fun isChat(): Boolean = chat != null - fun isNullableVariant(): Boolean = nullableVariant != null - fun asCompletion(): Completion = completion.getOrThrow("completion") fun asChat(): Chat = chat.getOrThrow("chat") - fun asNullableVariant(): NullableVariant = nullableVariant.getOrThrow("nullableVariant") - fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { completion != null -> visitor.visitCompletion(completion) chat != null -> visitor.visitChat(chat) - nullableVariant != null -> visitor.visitNullableVariant(nullableVariant) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Prompt = apply { - if (!validated) { - if (completion == null && chat == null && nullableVariant == null) { - throw BraintrustInvalidDataException("Unknown Prompt: $_json") - } - completion?.validate() - chat?.validate() - nullableVariant?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitCompletion(completion: Completion) { + completion.validate() + } + + override fun visitChat(chat: Chat) { + chat.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -2401,58 +923,53 @@ private constructor( return true } - return other is Prompt && - this.completion == other.completion && - this.chat == other.chat && - this.nullableVariant == other.nullableVariant + return /* spotless:off */ other is Prompt && completion == other.completion && chat == other.chat /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - completion, - chat, - nullableVariant, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(completion, chat) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { completion != null -> "Prompt{completion=$completion}" chat != null -> "Prompt{chat=$chat}" - nullableVariant != null -> "Prompt{nullableVariant=$nullableVariant}" _json != null -> "Prompt{_unknown=$_json}" else -> throw IllegalStateException("Invalid Prompt") } - } companion object { @JvmStatic fun ofCompletion(completion: Completion) = Prompt(completion = completion) @JvmStatic fun ofChat(chat: Chat) = Prompt(chat = chat) - - @JvmStatic - fun ofNullableVariant(nullableVariant: NullableVariant) = - Prompt(nullableVariant = nullableVariant) } + /** An interface that defines how to map each variant of [Prompt] to a value of type [T]. */ interface Visitor { fun visitCompletion(completion: Completion): T fun visitChat(chat: Chat): T - fun visitNullableVariant(nullableVariant: NullableVariant): T - + /** + * Maps an unknown variant of [Prompt] to a value of type [T]. + * + * An instance of [Prompt] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Prompt: $json") } } - class Deserializer : BaseDeserializer(Prompt::class) { + internal class Deserializer : BaseDeserializer(Prompt::class) { override fun ObjectCodec.deserialize(node: JsonNode): Prompt { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Prompt(completion = it, _json = json) @@ -2461,131 +978,144 @@ private constructor( ?.let { return Prompt(chat = it, _json = json) } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return Prompt(nullableVariant = it, _json = json) - } return Prompt(_json = json) } } - class Serializer : BaseSerializer(Prompt::class) { + internal class Serializer : BaseSerializer(Prompt::class) { override fun serialize( value: Prompt, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.completion != null -> generator.writeObject(value.completion) value.chat != null -> generator.writeObject(value.chat) - value.nullableVariant != null -> generator.writeObject(value.nullableVariant) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Prompt") } } } - @JsonDeserialize(builder = Completion.Builder::class) @NoAutoDetect class Completion + @JsonCreator private constructor( - private val type: JsonField, - private val content: JsonField, - private val additionalProperties: Map, + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 content(): String = content.getRequired("content") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun content(): String = content.getRequired("content") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Completion = apply { - if (!validated) { - type() - content() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Completion = apply { + if (validated) { + return@apply } - return other is Completion && - this.type == other.type && - this.content == other.content && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - content, - additionalProperties, - ) - } - return hashCode + content() + type() + validated = true } - override fun toString() = - "Completion{type=$type, content=$content, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Completion]. + * + * The following fields are required: + * ```java + * .content() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Completion]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var content: JsonField = JsonMissing.of() + private var content: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(completion: Completion) = apply { - this.type = completion.type - this.content = completion.content - additionalProperties(completion.additionalProperties) + content = completion.content + type = completion.type + additionalProperties = completion.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun content(content: String) = content(JsonField.of(content)) - @JsonProperty("content") - @ExcludeMissing + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2593,183 +1123,335 @@ private constructor( 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 [Completion]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Completion = Completion( - type, - content, - additionalProperties.toUnmodifiable(), + checkRequired("content", content), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val COMPLETION = Type(JsonField.of("completion")) + @JvmField val COMPLETION = of("completion") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - COMPLETION, + COMPLETION } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { COMPLETION, + /** + * An enum member indicating that [Type] 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) { COMPLETION -> Value.COMPLETION 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { COMPLETION -> Known.COMPLETION else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Completion && content == other.content && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(content, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Completion{content=$content, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Chat.Builder::class) @NoAutoDetect class Chat + @JsonCreator private constructor( - private val type: JsonField, - private val messages: JsonField>, - private val tools: JsonField, - private val additionalProperties: Map, + @JsonProperty("messages") + @ExcludeMissing + private val messages: JsonField> = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonProperty("tools") + @ExcludeMissing + private val tools: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 messages(): List = messages.getRequired("messages") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun messages(): List = messages.getRequired("messages") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ fun tools(): Optional = Optional.ofNullable(tools.getNullable("tools")) - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("messages") @ExcludeMissing fun _messages() = messages - - @JsonProperty("tools") @ExcludeMissing fun _tools() = tools + /** + * Returns the raw JSON value of [messages]. + * + * Unlike [messages], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("messages") + @ExcludeMissing + fun _messages(): JsonField> = messages + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + /** + * Returns the raw JSON value of [tools]. + * + * Unlike [tools], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tools") @ExcludeMissing fun _tools(): JsonField = tools @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Chat = apply { - if (!validated) { - type() - messages() - tools() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Chat = apply { + if (validated) { + return@apply } - return other is Chat && - this.type == other.type && - this.messages == other.messages && - this.tools == other.tools && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - messages, - tools, - additionalProperties, - ) - } - return hashCode + messages().forEach { it.validate() } + type() + tools() + validated = true } - override fun toString() = - "Chat{type=$type, messages=$messages, tools=$tools, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Chat]. + * + * The following fields are required: + * ```java + * .messages() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Chat]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var messages: JsonField> = JsonMissing.of() + private var messages: JsonField>? = null + private var type: JsonField? = null private var tools: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(chat: Chat) = apply { - this.type = chat.type - this.messages = chat.messages - this.tools = chat.tools - additionalProperties(chat.additionalProperties) + messages = chat.messages.map { it.toMutableList() } + type = chat.type + tools = chat.tools + additionalProperties = chat.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun messages(messages: List) = messages(JsonField.of(messages)) - @JsonProperty("messages") - @ExcludeMissing + /** + * Sets [Builder.messages] to an arbitrary JSON value. + * + * You should usually call [Builder.messages] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ fun messages(messages: JsonField>) = apply { - this.messages = messages + this.messages = messages.map { it.toMutableList() } + } + + /** + * Adds a single [Message] to [messages]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMessage(message: Message) = apply { + messages = + (messages ?: JsonField.of(mutableListOf())).also { + checkKnown("messages", it).add(message) + } } + /** Alias for calling [addMessage] with `Message.ofSystem(system)`. */ + fun addMessage(system: Message.System) = addMessage(Message.ofSystem(system)) + + /** Alias for calling [addMessage] with `Message.ofUser(user)`. */ + fun addMessage(user: Message.User) = addMessage(Message.ofUser(user)) + + /** Alias for calling [addMessage] with `Message.ofAssistant(assistant)`. */ + fun addMessage(assistant: Message.Assistant) = + addMessage(Message.ofAssistant(assistant)) + + /** Alias for calling [addMessage] with `Message.ofTool(tool)`. */ + fun addMessage(tool: Message.Tool) = addMessage(Message.ofTool(tool)) + + /** Alias for calling [addMessage] with `Message.ofFunction(function)`. */ + fun addMessage(function: Message.Function) = + addMessage(Message.ofFunction(function)) + + /** Alias for calling [addMessage] with `Message.ofFallback(fallback)`. */ + fun addMessage(fallback: Message.Fallback) = + addMessage(Message.ofFallback(fallback)) + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun tools(tools: String) = tools(JsonField.of(tools)) - @JsonProperty("tools") - @ExcludeMissing + /** + * Sets [Builder.tools] to an arbitrary JSON value. + * + * You should usually call [Builder.tools] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun tools(tools: JsonField) = apply { this.tools = tools } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -2777,12 +1459,33 @@ private constructor( 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 [Chat]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .messages() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Chat = Chat( - type, - messages.map { it.toUnmodifiable() }, + checkRequired("messages", messages).map { it.toImmutable() }, + checkRequired("type", type), tools, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } @@ -2799,8 +1502,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun system(): Optional = Optional.ofNullable(system) fun user(): Optional = Optional.ofNullable(user) @@ -2851,26 +1552,41 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): Message = apply { - if (!validated) { - if ( - system == null && - user == null && - assistant == null && - tool == null && - function == null && - fallback == null - ) { - throw BraintrustInvalidDataException("Unknown Message: $_json") - } - system?.validate() - user?.validate() - assistant?.validate() - tool?.validate() - function?.validate() - fallback?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitSystem(system: System) { + system.validate() + } + + override fun visitUser(user: User) { + user.validate() + } + + override fun visitAssistant(assistant: Assistant) { + assistant.validate() + } + + override fun visitTool(tool: Tool) { + tool.validate() + } + + override fun visitFunction(function: Function) { + function.validate() + } + + override fun visitFallback(fallback: Fallback) { + fallback.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -2878,28 +1594,13 @@ private constructor( return true } - return other is Message && - this.system == other.system && - this.user == other.user && - this.assistant == other.assistant && - this.tool == other.tool && - this.function == other.function && - this.fallback == other.fallback + return /* spotless:off */ other is Message && system == other.system && user == other.user && assistant == other.assistant && tool == other.tool && function == other.function && fallback == other.fallback /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - system, - user, - assistant, - tool, - function, - fallback, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(system, user, assistant, tool, function, fallback) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { system != null -> "Message{system=$system}" user != null -> "Message{user=$user}" assistant != null -> "Message{assistant=$assistant}" @@ -2909,7 +1610,6 @@ private constructor( _json != null -> "Message{_unknown=$_json}" else -> throw IllegalStateException("Invalid Message") } - } companion object { @@ -2927,6 +1627,10 @@ private constructor( @JvmStatic fun ofFallback(fallback: Fallback) = Message(fallback = fallback) } + /** + * An interface that defines how to map each variant of [Message] to a value of type + * [T]. + */ interface Visitor { fun visitSystem(system: System): T @@ -2941,15 +1645,26 @@ private constructor( fun visitFallback(fallback: Fallback): T + /** + * Maps an unknown variant of [Message] to a value of type [T]. + * + * An instance of [Message] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Message: $json") } } - class Deserializer : BaseDeserializer(Message::class) { + internal class Deserializer : BaseDeserializer(Message::class) { override fun ObjectCodec.deserialize(node: JsonNode): Message { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return Message(system = it, _json = json) @@ -2979,12 +1694,12 @@ private constructor( } } - class Serializer : BaseSerializer(Message::class) { + internal class Serializer : BaseSerializer(Message::class) { override fun serialize( value: Message, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.system != null -> generator.writeObject(value.system) @@ -2999,425 +1714,660 @@ private constructor( } } - @JsonDeserialize(builder = System.Builder::class) @NoAutoDetect class System + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - @JsonProperty("content") @ExcludeMissing fun _content() = content - - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): System = apply { - if (!validated) { - content() - role() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): System = apply { + if (validated) { + return@apply } - return other is System && - this.content == other.content && - this.role == other.role && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - name, - additionalProperties, - ) - } - return hashCode + role() + content() + name() + validated = true } - override fun toString() = - "System{content=$content, role=$role, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [System]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [System]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(system: System) = apply { - this.content = system.content - this.role = system.role - this.name = system.name - additionalProperties(system.additionalProperties) + role = system.role + content = system.content + name = system.name + additionalProperties = system.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [System]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): System = System( + checkRequired("role", role), content, - role, name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val SYSTEM = Role(JsonField.of("system")) + @JvmField val SYSTEM = of("system") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - SYSTEM, + SYSTEM } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { SYSTEM, + /** + * An enum member indicating that [Role] 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) { SYSTEM -> Value.SYSTEM 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { SYSTEM -> Known.SYSTEM else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is System && role == other.role && content == other.content && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "System{role=$role, content=$content, name=$name, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = User.Builder::class) @NoAutoDetect class User + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) - @JsonProperty("content") @ExcludeMissing fun _content() = content - - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): User = apply { - if (!validated) { - content() - role() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): User = apply { + if (validated) { + return@apply } - return other is User && - this.content == other.content && - this.role == other.role && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - name, - additionalProperties, - ) - } - return hashCode + role() + content().ifPresent { it.validate() } + name() + validated = true } - override fun toString() = - "User{content=$content, role=$role, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [User]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [User]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(user: User) = apply { - this.content = user.content - this.role = user.role - this.name = user.name - additionalProperties(user.additionalProperties) + role = user.role + content = user.content + name = user.name + additionalProperties = user.additionalProperties.toMutableMap() } + fun role(role: Role) = role(JsonField.of(role)) + + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun role(role: JsonField) = apply { this.role = role } + fun content(content: Content) = content(JsonField.of(content)) - @JsonProperty("content") - @ExcludeMissing + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) + /** Alias for calling [content] with `Content.ofText(text)`. */ + fun content(text: String) = content(Content.ofText(text)) - @JsonProperty("role") - @ExcludeMissing - fun role(role: JsonField) = apply { this.role = role } + /** Alias for calling [content] with `Content.ofArray(array)`. */ + fun contentOfArray(array: List) = + content(Content.ofArray(array)) fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [User]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): User = User( + checkRequired("role", role), content, - role, name, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val USER = Role(JsonField.of("user")) + @JvmField val USER = of("user") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - USER, + USER } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { USER, + /** + * An enum member indicating that [Role] 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) { USER -> Value.USER 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { USER -> Known.USER else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } @JsonDeserialize(using = Content.Deserializer::class) @JsonSerialize(using = Content.Serializer::class) class Content private constructor( - private val string: String? = null, - private val chatCompletionContentParts: List? = - null, + private val text: String? = null, + private val array: List? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - - fun string(): Optional = Optional.ofNullable(string) + fun text(): Optional = Optional.ofNullable(text) - fun chatCompletionContentParts(): - Optional> = - Optional.ofNullable(chatCompletionContentParts) + fun array(): Optional> = + Optional.ofNullable(array) - fun isString(): Boolean = string != null + fun isText(): Boolean = text != null - fun isChatCompletionContentParts(): Boolean = - chatCompletionContentParts != null + fun isArray(): Boolean = array != null - fun asString(): String = string.getOrThrow("string") + fun asText(): String = text.getOrThrow("text") - fun asChatCompletionContentParts(): List = - chatCompletionContentParts.getOrThrow("chatCompletionContentParts") + fun asArray(): List = array.getOrThrow("array") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - string != null -> visitor.visitString(string) - chatCompletionContentParts != null -> - visitor.visitChatCompletionContentParts( - chatCompletionContentParts - ) + text != null -> visitor.visitText(text) + array != null -> visitor.visitArray(array) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): Content = apply { - if (!validated) { - if (string == null && chatCompletionContentParts == null) { - throw BraintrustInvalidDataException("Unknown Content: $_json") - } - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitText(text: String) {} + + override fun visitArray( + array: List + ) { + array.forEach { it.validate() } + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -3425,81 +2375,85 @@ private constructor( return true } - return other is Content && - this.string == other.string && - this.chatCompletionContentParts == other.chatCompletionContentParts + return /* spotless:off */ other is Content && text == other.text && array == other.array /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, chatCompletionContentParts) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(text, array) /* spotless:on */ - override fun toString(): String { - return when { - string != null -> "Content{string=$string}" - chatCompletionContentParts != null -> - "Content{chatCompletionContentParts=$chatCompletionContentParts}" + override fun toString(): String = + when { + text != null -> "Content{text=$text}" + array != null -> "Content{array=$array}" _json != null -> "Content{_unknown=$_json}" else -> throw IllegalStateException("Invalid Content") } - } companion object { - @JvmStatic fun ofString(string: String) = Content(string = string) + @JvmStatic fun ofText(text: String) = Content(text = text) @JvmStatic - fun ofChatCompletionContentParts( - chatCompletionContentParts: List - ) = Content(chatCompletionContentParts = chatCompletionContentParts) + fun ofArray(array: List) = + Content(array = array) } + /** + * An interface that defines how to map each variant of [Content] to a value + * of type [T]. + */ interface Visitor { - fun visitString(string: String): T + fun visitText(text: String): T - fun visitChatCompletionContentParts( - chatCompletionContentParts: List - ): T + fun visitArray(array: List): T + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Content: $json") } } - class Deserializer : BaseDeserializer(Content::class) { + internal class Deserializer : BaseDeserializer(Content::class) { override fun ObjectCodec.deserialize(node: JsonNode): Content { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { - return Content(string = it, _json = json) + return Content(text = it, _json = json) } tryDeserialize( node, - jacksonTypeRef>() - ) + jacksonTypeRef>(), + ) { + it.forEach { it.validate() } + } ?.let { - return Content( - chatCompletionContentParts = it, - _json = json - ) + return Content(array = it, _json = json) } return Content(_json = json) } } - class Serializer : BaseSerializer(Content::class) { + internal class Serializer : BaseSerializer(Content::class) { override fun serialize( value: Content, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.string != null -> generator.writeObject(value.string) - value.chatCompletionContentParts != null -> - generator.writeObject(value.chatCompletionContentParts) + value.text != null -> generator.writeObject(value.text) + value.array != null -> generator.writeObject(value.array) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid Content") } @@ -3510,71 +2464,59 @@ private constructor( @JsonSerialize(using = ChatCompletionContentPart.Serializer::class) class ChatCompletionContentPart private constructor( - private val chatCompletionContentPartText: - ChatCompletionContentPartText? = - null, - private val chatCompletionContentPartImage: - ChatCompletionContentPartImage? = - null, + private val text: ChatCompletionContentPartText? = null, + private val image: ChatCompletionContentPartImage? = null, private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - - fun chatCompletionContentPartText(): - Optional = - Optional.ofNullable(chatCompletionContentPartText) + fun text(): Optional = + Optional.ofNullable(text) - fun chatCompletionContentPartImage(): - Optional = - Optional.ofNullable(chatCompletionContentPartImage) + fun image(): Optional = + Optional.ofNullable(image) - fun isChatCompletionContentPartText(): Boolean = - chatCompletionContentPartText != null + fun isText(): Boolean = text != null - fun isChatCompletionContentPartImage(): Boolean = - chatCompletionContentPartImage != null + fun isImage(): Boolean = image != null - fun asChatCompletionContentPartText(): ChatCompletionContentPartText = - chatCompletionContentPartText.getOrThrow( - "chatCompletionContentPartText" - ) + fun asText(): ChatCompletionContentPartText = text.getOrThrow("text") - fun asChatCompletionContentPartImage(): ChatCompletionContentPartImage = - chatCompletionContentPartImage.getOrThrow( - "chatCompletionContentPartImage" - ) + fun asImage(): ChatCompletionContentPartImage = + image.getOrThrow("image") fun _json(): Optional = Optional.ofNullable(_json) fun accept(visitor: Visitor): T { return when { - chatCompletionContentPartText != null -> - visitor.visitChatCompletionContentPartText( - chatCompletionContentPartText - ) - chatCompletionContentPartImage != null -> - visitor.visitChatCompletionContentPartImage( - chatCompletionContentPartImage - ) + text != null -> visitor.visitText(text) + image != null -> visitor.visitImage(image) else -> visitor.unknown(_json) } } + private var validated: Boolean = false + fun validate(): ChatCompletionContentPart = apply { - if (!validated) { - if ( - chatCompletionContentPartText == null && - chatCompletionContentPartImage == null - ) { - throw BraintrustInvalidDataException( - "Unknown ChatCompletionContentPart: $_json" - ) - } - chatCompletionContentPartText?.validate() - chatCompletionContentPartImage?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitText( + text: ChatCompletionContentPartText + ) { + text.validate() + } + + override fun visitImage( + image: ChatCompletionContentPartImage + ) { + image.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -3582,65 +2524,56 @@ private constructor( return true } - return other is ChatCompletionContentPart && - this.chatCompletionContentPartText == - other.chatCompletionContentPartText && - this.chatCompletionContentPartImage == - other.chatCompletionContentPartImage + return /* spotless:off */ other is ChatCompletionContentPart && text == other.text && image == other.image /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - chatCompletionContentPartText, - chatCompletionContentPartImage - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(text, image) /* spotless:on */ - override fun toString(): String { - return when { - chatCompletionContentPartText != null -> - "ChatCompletionContentPart{chatCompletionContentPartText=$chatCompletionContentPartText}" - chatCompletionContentPartImage != null -> - "ChatCompletionContentPart{chatCompletionContentPartImage=$chatCompletionContentPartImage}" + override fun toString(): String = + when { + text != null -> "ChatCompletionContentPart{text=$text}" + image != null -> "ChatCompletionContentPart{image=$image}" _json != null -> "ChatCompletionContentPart{_unknown=$_json}" else -> throw IllegalStateException( "Invalid ChatCompletionContentPart" ) } - } companion object { @JvmStatic - fun ofChatCompletionContentPartText( - chatCompletionContentPartText: ChatCompletionContentPartText - ) = - ChatCompletionContentPart( - chatCompletionContentPartText = - chatCompletionContentPartText - ) + fun ofText(text: ChatCompletionContentPartText) = + ChatCompletionContentPart(text = text) @JvmStatic - fun ofChatCompletionContentPartImage( - chatCompletionContentPartImage: ChatCompletionContentPartImage - ) = - ChatCompletionContentPart( - chatCompletionContentPartImage = - chatCompletionContentPartImage - ) + fun ofImage(image: ChatCompletionContentPartImage) = + ChatCompletionContentPart(image = image) } + /** + * An interface that defines how to map each variant of + * [ChatCompletionContentPart] to a value of type [T]. + */ interface Visitor { - fun visitChatCompletionContentPartText( - chatCompletionContentPartText: ChatCompletionContentPartText - ): T - - fun visitChatCompletionContentPartImage( - chatCompletionContentPartImage: ChatCompletionContentPartImage - ): T - + fun visitText(text: ChatCompletionContentPartText): T + + fun visitImage(image: ChatCompletionContentPartImage): T + + /** + * Maps an unknown variant of [ChatCompletionContentPart] to a value + * of type [T]. + * + * An instance of [ChatCompletionContentPart] can contain an unknown + * variant if it was deserialized from data that doesn't match any + * known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default + * implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException( "Unknown ChatCompletionContentPart: $json" @@ -3648,7 +2581,7 @@ private constructor( } } - class Deserializer : + internal class Deserializer : BaseDeserializer( ChatCompletionContentPart::class ) { @@ -3657,28 +2590,29 @@ private constructor( node: JsonNode ): ChatCompletionContentPart { val json = JsonValue.fromJsonNode(node) + tryDeserialize( node, - jacksonTypeRef() + jacksonTypeRef(), ) { it.validate() } ?.let { return ChatCompletionContentPart( - chatCompletionContentPartText = it, - _json = json + text = it, + _json = json, ) } tryDeserialize( node, - jacksonTypeRef() + jacksonTypeRef(), ) { it.validate() } ?.let { return ChatCompletionContentPart( - chatCompletionContentPartImage = it, - _json = json + image = it, + _json = json, ) } @@ -3686,7 +2620,7 @@ private constructor( } } - class Serializer : + internal class Serializer : BaseSerializer( ChatCompletionContentPart::class ) { @@ -3694,17 +2628,11 @@ private constructor( override fun serialize( value: ChatCompletionContentPart, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { - value.chatCompletionContentPartText != null -> - generator.writeObject( - value.chatCompletionContentPartText - ) - value.chatCompletionContentPartImage != null -> - generator.writeObject( - value.chatCompletionContentPartImage - ) + value.text != null -> generator.writeObject(value.text) + value.image != null -> generator.writeObject(value.image) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException( @@ -3715,466 +2643,771 @@ private constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is User && role == other.role && content == other.content && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "User{role=$role, content=$content, name=$name, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Assistant.Builder::class) @NoAutoDetect class Assistant + @JsonCreator private constructor( - private val role: JsonField, - private val content: JsonField, - private val functionCall: JsonField, - private val name: JsonField, - private val toolCalls: JsonField>, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("function_call") + @ExcludeMissing + private val functionCall: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("tool_calls") + @ExcludeMissing + private val toolCalls: JsonField> = + JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun functionCall(): Optional = Optional.ofNullable(functionCall.getNullable("function_call")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun toolCalls(): Optional> = Optional.ofNullable(toolCalls.getNullable("tool_calls")) - @JsonProperty("role") @ExcludeMissing fun _role() = role - - @JsonProperty("content") @ExcludeMissing fun _content() = content - + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [functionCall]. + * + * Unlike [functionCall], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("function_call") @ExcludeMissing - fun _functionCall() = functionCall - - @JsonProperty("name") @ExcludeMissing fun _name() = name - - @JsonProperty("tool_calls") @ExcludeMissing fun _toolCalls() = toolCalls + fun _functionCall(): JsonField = functionCall + + /** + * 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 [toolCalls]. + * + * Unlike [toolCalls], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("tool_calls") + @ExcludeMissing + fun _toolCalls(): JsonField> = toolCalls @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Assistant = apply { - if (!validated) { - role() - content() - functionCall().map { it.validate() } - name() - toolCalls().map { it.forEach { it.validate() } } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Assistant = apply { + if (validated) { + return@apply } - return other is Assistant && - this.role == other.role && - this.content == other.content && - this.functionCall == other.functionCall && - this.name == other.name && - this.toolCalls == other.toolCalls && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - role, - content, - functionCall, - name, - toolCalls, - additionalProperties, - ) - } - return hashCode + role() + content() + functionCall().ifPresent { it.validate() } + name() + toolCalls().ifPresent { it.forEach { it.validate() } } + validated = true } - override fun toString() = - "Assistant{role=$role, content=$content, functionCall=$functionCall, name=$name, toolCalls=$toolCalls, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Assistant]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Assistant]. */ + class Builder internal constructor() { - private var role: JsonField = JsonMissing.of() + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() private var functionCall: JsonField = JsonMissing.of() private var name: JsonField = JsonMissing.of() - private var toolCalls: JsonField> = - JsonMissing.of() + private var toolCalls: + JsonField>? = + null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(assistant: Assistant) = apply { - this.role = assistant.role - this.content = assistant.content - this.functionCall = assistant.functionCall - this.name = assistant.name - this.toolCalls = assistant.toolCalls - additionalProperties(assistant.additionalProperties) + role = assistant.role + content = assistant.content + functionCall = assistant.functionCall + name = assistant.name + toolCalls = assistant.toolCalls.map { it.toMutableList() } + additionalProperties = assistant.additionalProperties.toMutableMap() } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun role(role: JsonField) = apply { this.role = role } - fun content(content: String) = content(JsonField.of(content)) + fun content(content: String?) = content(JsonField.ofNullable(content)) - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) - fun functionCall(functionCall: FunctionCall) = - functionCall(JsonField.of(functionCall)) + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } - @JsonProperty("function_call") - @ExcludeMissing + fun functionCall(functionCall: FunctionCall?) = + functionCall(JsonField.ofNullable(functionCall)) + + /** + * Alias for calling [Builder.functionCall] with + * `functionCall.orElse(null)`. + */ + fun functionCall(functionCall: Optional) = + functionCall(functionCall.getOrNull()) + + /** + * Sets [Builder.functionCall] to an arbitrary JSON value. + * + * You should usually call [Builder.functionCall] with a well-typed + * [FunctionCall] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun functionCall(functionCall: JsonField) = apply { this.functionCall = functionCall } - fun name(name: String) = name(JsonField.of(name)) + fun name(name: String?) = name(JsonField.ofNullable(name)) - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) - fun toolCalls(toolCalls: List) = - toolCalls(JsonField.of(toolCalls)) + /** + * 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 } - @JsonProperty("tool_calls") - @ExcludeMissing + fun toolCalls(toolCalls: List?) = + toolCalls(JsonField.ofNullable(toolCalls)) + + /** Alias for calling [Builder.toolCalls] with `toolCalls.orElse(null)`. */ + fun toolCalls(toolCalls: Optional>) = + toolCalls(toolCalls.getOrNull()) + + /** + * Sets [Builder.toolCalls] to an arbitrary JSON value. + * + * You should usually call [Builder.toolCalls] with a well-typed + * `List` value instead. This method is + * primarily for setting the field to an undocumented or not yet supported + * value. + */ fun toolCalls(toolCalls: JsonField>) = apply { - this.toolCalls = toolCalls + this.toolCalls = toolCalls.map { it.toMutableList() } } + /** + * Adds a single [ChatCompletionMessageToolCall] to [toolCalls]. + * + * @throws IllegalStateException if the field was previously set to a + * non-list. + */ + fun addToolCall(toolCall: ChatCompletionMessageToolCall) = apply { + toolCalls = + (toolCalls ?: JsonField.of(mutableListOf())).also { + checkKnown("toolCalls", it).add(toolCall) + } + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Assistant]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Assistant = Assistant( - role, + checkRequired("role", role), content, functionCall, name, - toolCalls.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + (toolCalls ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val ASSISTANT = Role(JsonField.of("assistant")) + @JvmField val ASSISTANT = of("assistant") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - ASSISTANT, + ASSISTANT } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { ASSISTANT, + /** + * An enum member indicating that [Role] 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) { ASSISTANT -> Value.ASSISTANT 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { ASSISTANT -> Known.ASSISTANT else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } - @JsonDeserialize(builder = FunctionCall.Builder::class) @NoAutoDetect class FunctionCall + @JsonCreator private constructor( - private val arguments: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("arguments") + @ExcludeMissing + private val arguments: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 arguments(): String = arguments.getRequired("arguments") + /** + * @throws BraintrustInvalidDataException 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") - @JsonProperty("arguments") @ExcludeMissing fun _arguments() = arguments + /** + * Returns the raw JSON value of [arguments]. + * + * Unlike [arguments], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("arguments") + @ExcludeMissing + fun _arguments(): JsonField = arguments - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): FunctionCall = apply { - if (!validated) { - arguments() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): FunctionCall = apply { + if (validated) { + return@apply } - return other is FunctionCall && - this.arguments == other.arguments && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - arguments, - name, - additionalProperties, - ) - } - return hashCode + arguments() + name() + validated = true } - override fun toString() = - "FunctionCall{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of + * [FunctionCall]. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [FunctionCall]. */ + class Builder internal constructor() { - private var arguments: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var arguments: JsonField? = null + private var name: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(functionCall: FunctionCall) = apply { - this.arguments = functionCall.arguments - this.name = functionCall.name - additionalProperties(functionCall.additionalProperties) + arguments = functionCall.arguments + name = functionCall.name + additionalProperties = + functionCall.additionalProperties.toMutableMap() } fun arguments(arguments: String) = arguments(JsonField.of(arguments)) - @JsonProperty("arguments") - @ExcludeMissing + /** + * Sets [Builder.arguments] to an arbitrary JSON value. + * + * You should usually call [Builder.arguments] with a well-typed + * [String] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ fun arguments(arguments: JsonField) = apply { this.arguments = arguments } fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [FunctionCall]. + * + * Further updates to this [Builder] will not mutate the returned + * instance. + * + * The following fields are required: + * ```java + * .arguments() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): FunctionCall = FunctionCall( - arguments, - name, - additionalProperties.toUnmodifiable(), + checkRequired("arguments", arguments), + checkRequired("name", name), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionCall && arguments == other.arguments && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(arguments, name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCall{arguments=$arguments, name=$name, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Assistant && role == other.role && content == other.content && functionCall == other.functionCall && name == other.name && toolCalls == other.toolCalls && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, functionCall, name, toolCalls, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Assistant{role=$role, content=$content, functionCall=$functionCall, name=$name, toolCalls=$toolCalls, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Tool.Builder::class) @NoAutoDetect class Tool + @JsonCreator private constructor( - private val content: JsonField, - private val role: JsonField, - private val toolCallId: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonProperty("tool_call_id") + @ExcludeMissing + private val toolCallId: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - fun role(): Role = role.getRequired("role") - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun toolCallId(): Optional = Optional.ofNullable(toolCallId.getNullable("tool_call_id")) - @JsonProperty("content") @ExcludeMissing fun _content() = content - - @JsonProperty("role") @ExcludeMissing fun _role() = role - - @JsonProperty("tool_call_id") @ExcludeMissing fun _toolCallId() = toolCallId + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [toolCallId]. + * + * Unlike [toolCallId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("tool_call_id") + @ExcludeMissing + fun _toolCallId(): JsonField = toolCallId @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Tool = apply { - if (!validated) { - content() - role() - toolCallId() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Tool = apply { + if (validated) { + return@apply } - return other is Tool && - this.content == other.content && - this.role == other.role && - this.toolCallId == other.toolCallId && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - role, - toolCallId, - additionalProperties, - ) - } - return hashCode + role() + content() + toolCallId() + validated = true } - override fun toString() = - "Tool{content=$content, role=$role, toolCallId=$toolCallId, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Tool]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Tool]. */ + class Builder internal constructor() { + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var toolCallId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(tool: Tool) = apply { - this.content = tool.content - this.role = tool.role - this.toolCallId = tool.toolCallId - additionalProperties(tool.additionalProperties) + role = tool.role + content = tool.content + toolCallId = tool.toolCallId + additionalProperties = tool.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun toolCallId(toolCallId: String) = toolCallId(JsonField.of(toolCallId)) - @JsonProperty("tool_call_id") - @ExcludeMissing + /** + * Sets [Builder.toolCallId] to an arbitrary JSON value. + * + * You should usually call [Builder.toolCallId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun toolCallId(toolCallId: JsonField) = apply { this.toolCallId = toolCallId } @@ -4182,561 +3415,867 @@ private constructor( fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Tool]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Tool = Tool( + checkRequired("role", role), content, - role, toolCallId, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val TOOL = Role(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - TOOL, + TOOL } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { TOOL, + /** + * An enum member indicating that [Role] 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) { TOOL -> Value.TOOL 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { TOOL -> Known.TOOL else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Tool && role == other.role && content == other.content && toolCallId == other.toolCallId && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, toolCallId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Tool{role=$role, content=$content, toolCallId=$toolCallId, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val content: JsonField, - private val name: JsonField, - private val role: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun content(): Optional = - Optional.ofNullable(content.getNullable("content")) - + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") - @JsonProperty("content") @ExcludeMissing fun _content() = content - - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ + fun content(): Optional = + Optional.ofNullable(content.getNullable("content")) - @JsonProperty("role") @ExcludeMissing fun _role() = role + /** + * 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 [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - content() - name() - role() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.content == other.content && - this.name == other.name && - this.role == other.role && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - content, - name, - role, - additionalProperties, - ) - } - return hashCode + name() + role() + content() + validated = true } - override fun toString() = - "Function{content=$content, name=$name, role=$role, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .name() + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { + private var name: JsonField? = null + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var role: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.content = function.content - this.name = function.name - this.role = function.role - additionalProperties(function.additionalProperties) + name = function.name + role = function.role + content = function.content + additionalProperties = function.additionalProperties.toMutableMap() } - fun content(content: String) = content(JsonField.of(content)) - - @JsonProperty("content") - @ExcludeMissing - fun content(content: JsonField) = apply { this.content = content } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun role(role: JsonField) = apply { this.role = role } + fun content(content: String) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( + checkRequired("name", name), + checkRequired("role", role), content, - name, - role, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val FUNCTION = Role(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { FUNCTION, + /** + * An enum member indicating that [Role] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && name == other.name && role == other.role && content == other.content && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, role, content, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{name=$name, role=$role, content=$content, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Fallback.Builder::class) @NoAutoDetect class Fallback + @JsonCreator private constructor( - private val role: JsonField, - private val content: JsonField, - private val additionalProperties: Map, + @JsonProperty("role") + @ExcludeMissing + private val role: JsonField = JsonMissing.of(), + @JsonProperty("content") + @ExcludeMissing + private val content: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException 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 role(): Role = role.getRequired("role") + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected + * type (e.g. if the server responded with an unexpected value). + */ fun content(): Optional = Optional.ofNullable(content.getNullable("content")) - @JsonProperty("role") @ExcludeMissing fun _role() = role - - @JsonProperty("content") @ExcludeMissing fun _content() = content + /** + * Returns the raw JSON value of [role]. + * + * Unlike [role], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonField = role + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("content") + @ExcludeMissing + fun _content(): JsonField = content @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Fallback = apply { - if (!validated) { - role() - content() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Fallback = apply { + if (validated) { + return@apply } - return other is Fallback && - this.role == other.role && - this.content == other.content && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - role, - content, - additionalProperties, - ) - } - return hashCode + role() + content() + validated = true } - override fun toString() = - "Fallback{role=$role, content=$content, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Fallback]. + * + * The following fields are required: + * ```java + * .role() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Fallback]. */ + class Builder internal constructor() { - private var role: JsonField = JsonMissing.of() + private var role: JsonField? = null private var content: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(fallback: Fallback) = apply { - this.role = fallback.role - this.content = fallback.content - additionalProperties(fallback.additionalProperties) + role = fallback.role + content = fallback.content + additionalProperties = fallback.additionalProperties.toMutableMap() } fun role(role: Role) = role(JsonField.of(role)) - @JsonProperty("role") - @ExcludeMissing + /** + * Sets [Builder.role] to an arbitrary JSON value. + * + * You should usually call [Builder.role] with a well-typed [Role] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun role(role: JsonField) = apply { this.role = role } - fun content(content: String) = content(JsonField.of(content)) + fun content(content: String?) = content(JsonField.ofNullable(content)) - @JsonProperty("content") - @ExcludeMissing + /** Alias for calling [Builder.content] with `content.orElse(null)`. */ + fun content(content: Optional) = content(content.getOrNull()) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ fun content(content: JsonField) = apply { this.content = content } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Fallback]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .role() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Fallback = Fallback( - role, + checkRequired("role", role), content, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } class Role @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + 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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Role && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val MODEL = Role(JsonField.of("model")) + @JvmField val MODEL = of("model") @JvmStatic fun of(value: String) = Role(JsonField.of(value)) } + /** An enum containing [Role]'s known values. */ enum class Known { - MODEL, + MODEL } + /** + * An enum containing [Role]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Role] 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 { MODEL, + /** + * An enum member indicating that [Role] 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) { MODEL -> Value.MODEL 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ fun known(): Known = when (this) { MODEL -> Known.MODEL else -> throw BraintrustInvalidDataException("Unknown Role: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - } + /** + * 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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Role && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + override fun toString() = value.toString() + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Fallback && role == other.role && content == other.content && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is Type && this.value == other.value - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(role, content, additionalProperties) } + /* spotless:on */ - override fun hashCode() = value.hashCode() + override fun hashCode(): Int = hashCode - override fun toString() = value.toString() + override fun toString() = + "Fallback{role=$role, content=$content, additionalProperties=$additionalProperties}" + } + } + + class Type @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 CHAT = Type(JsonField.of("chat")) + @JvmField val CHAT = of("chat") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - CHAT, + CHAT } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { CHAT, + /** + * An enum member indicating that [Type] 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) { CHAT -> Value.CHAT 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { CHAT -> Known.CHAT else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() - } - } - - @JsonDeserialize(builder = NullableVariant.Builder::class) - @NoAutoDetect - class NullableVariant - private constructor( - private val additionalProperties: Map, - ) { + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - private var hashCode: Int = 0 + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + override fun hashCode() = value.hashCode() - fun validate(): NullableVariant = apply { - if (!validated) { - validated = true - } + override fun toString() = value.toString() } - fun toBuilder() = Builder().from(this) - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is NullableVariant && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode - } - - override fun toString() = "NullableVariant{additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() + return /* spotless:off */ other is Chat && messages == other.messages && type == other.type && tools == other.tools && additionalProperties == other.additionalProperties /* spotless:on */ } - class Builder { - - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(nullableVariant: NullableVariant) = apply { - additionalProperties(nullableVariant.additionalProperties) - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(messages, type, tools, additionalProperties) } + /* spotless:on */ - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + override fun hashCode(): Int = hashCode - fun build(): NullableVariant = - NullableVariant(additionalProperties.toUnmodifiable()) - } + override fun toString() = + "Chat{messages=$messages, type=$type, tools=$tools, additionalProperties=$additionalProperties}" } } @@ -4749,8 +4288,6 @@ private constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun function(): Optional = Optional.ofNullable(function) fun global(): Optional = Optional.ofNullable(global) @@ -4773,15 +4310,25 @@ private constructor( } } + private var validated: Boolean = false + fun validate(): ToolFunction = apply { - if (!validated) { - if (function == null && global == null) { - throw BraintrustInvalidDataException("Unknown ToolFunction: $_json") - } - function?.validate() - global?.validate() - validated = true + if (validated) { + return@apply } + + accept( + object : Visitor { + override fun visitFunction(function: Function) { + function.validate() + } + + override fun visitGlobal(global: Global) { + global.validate() + } + } + ) + validated = true } override fun equals(other: Any?): Boolean { @@ -4789,23 +4336,18 @@ private constructor( return true } - return other is ToolFunction && - this.function == other.function && - this.global == other.global + return /* spotless:off */ other is ToolFunction && function == other.function && global == other.global /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(function, global) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(function, global) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { function != null -> "ToolFunction{function=$function}" global != null -> "ToolFunction{global=$global}" _json != null -> "ToolFunction{_unknown=$_json}" else -> throw IllegalStateException("Invalid ToolFunction") } - } companion object { @@ -4814,21 +4356,36 @@ private constructor( @JvmStatic fun ofGlobal(global: Global) = ToolFunction(global = global) } + /** + * An interface that defines how to map each variant of [ToolFunction] to a value of type + * [T]. + */ interface Visitor { fun visitFunction(function: Function): T fun visitGlobal(global: Global): T + /** + * Maps an unknown variant of [ToolFunction] to a value of type [T]. + * + * An instance of [ToolFunction] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown ToolFunction: $json") } } - class Deserializer : BaseDeserializer(ToolFunction::class) { + internal class Deserializer : BaseDeserializer(ToolFunction::class) { override fun ObjectCodec.deserialize(node: JsonNode): ToolFunction { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef()) { it.validate() } ?.let { return ToolFunction(function = it, _json = json) @@ -4842,12 +4399,12 @@ private constructor( } } - class Serializer : BaseSerializer(ToolFunction::class) { + internal class Serializer : BaseSerializer(ToolFunction::class) { override fun serialize( value: ToolFunction, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.function != null -> generator.writeObject(value.function) @@ -4858,105 +4415,123 @@ private constructor( } } - @JsonDeserialize(builder = Function.Builder::class) @NoAutoDetect class Function + @JsonCreator private constructor( - private val type: JsonField, - private val id: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") + @ExcludeMissing + private val id: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun id(): String = id.getRequired("id") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("id") @ExcludeMissing fun _id() = id + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Function = apply { - if (!validated) { - type() - id() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Function = apply { + if (validated) { + return@apply } - return other is Function && - this.type == other.type && - this.id == other.id && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - id, - additionalProperties, - ) - } - return hashCode + id() + type() + validated = true } - override fun toString() = - "Function{type=$type, id=$id, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Function]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var id: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(function: Function) = apply { - this.type = function.type - this.id = function.id - additionalProperties(function.additionalProperties) + id = function.id + type = function.type + additionalProperties = function.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun id(id: String) = id(JsonField.of(id)) - @JsonProperty("id") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -4964,165 +4539,267 @@ private constructor( 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Function = Function( - type, - id, - additionalProperties.toUnmodifiable(), + checkRequired("id", id), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val FUNCTION = Type(JsonField.of("function")) + @JvmField val FUNCTION = of("function") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - FUNCTION, + FUNCTION } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { FUNCTION, + /** + * An enum member indicating that [Type] 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) { FUNCTION -> Value.FUNCTION 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { FUNCTION -> Known.FUNCTION else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && id == other.id && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{id=$id, type=$type, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = Global.Builder::class) @NoAutoDetect class Global + @JsonCreator private constructor( - private val type: JsonField, - private val name: JsonField, - private val additionalProperties: Map, + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * @throws BraintrustInvalidDataException 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") + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") - fun name(): String = name.getRequired("name") - - @JsonProperty("type") @ExcludeMissing fun _type() = type + /** + * 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 - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Global = apply { - if (!validated) { - type() - name() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Global = apply { + if (validated) { + return@apply } - return other is Global && - this.type == other.type && - this.name == other.name && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - name, - additionalProperties, - ) - } - return hashCode + name() + type() + validated = true } - override fun toString() = - "Global{type=$type, name=$name, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Global]. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Global]. */ + class Builder internal constructor() { - private var type: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var name: JsonField? = null + private var type: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(global: Global) = apply { - this.type = global.type - this.name = global.name - additionalProperties(global.additionalProperties) + name = global.name + type = global.type + additionalProperties = global.additionalProperties.toMutableMap() } - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - fun name(name: String) = name(JsonField.of(name)) - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = @@ -5130,64 +4807,165 @@ private constructor( 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 [Global]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Global = Global( - type, - name, - additionalProperties.toUnmodifiable(), + checkRequired("name", name), + checkRequired("type", type), + additionalProperties.toImmutable(), ) } - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + class Type @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val GLOBAL = Type(JsonField.of("global")) + @JvmField val GLOBAL = of("global") @JvmStatic fun of(value: String) = Type(JsonField.of(value)) } + /** An enum containing [Type]'s known values. */ enum class Known { - GLOBAL, + GLOBAL } + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { GLOBAL, + /** + * An enum member indicating that [Type] 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) { GLOBAL -> Value.GLOBAL 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ fun known(): Known = when (this) { GLOBAL -> Known.GLOBAL else -> throw BraintrustInvalidDataException("Unknown Type: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Global && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Global{name=$name, type=$type, additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } + + return /* spotless:off */ other is PromptData && options == other.options && origin == other.origin && parser == other.parser && prompt == other.prompt && toolFunctions == other.toolFunctions && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(options, origin, parser, prompt, toolFunctions, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PromptData{options=$options, origin=$origin, parser=$parser, prompt=$prompt, toolFunctions=$toolFunctions, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptDeleteParams.kt index 586d384a..548ac609 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a prompt object by its id */ class PromptDeleteParams -constructor( +private constructor( private val promptId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Prompt id */ fun promptId(): String = promptId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptDeleteParams && - this.promptId == other.promptId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - promptId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "PromptDeleteParams{promptId=$promptId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptDeleteParams]. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var promptId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(promptDeleteParams: PromptDeleteParams) = apply { - this.promptId = promptDeleteParams.promptId - additionalQueryParams(promptDeleteParams.additionalQueryParams) - additionalHeaders(promptDeleteParams.additionalHeaders) - additionalBodyProperties(promptDeleteParams.additionalBodyProperties) + promptId = promptDeleteParams.promptId + additionalHeaders = promptDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = promptDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = promptDeleteParams.additionalBodyProperties.toMutableMap() } /** Prompt id */ fun promptId(promptId: String) = apply { this.promptId = promptId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [PromptDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): PromptDeleteParams = PromptDeleteParams( - checkNotNull(promptId) { "`promptId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("promptId", promptId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptDeleteParams && promptId == other.promptId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(promptId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "PromptDeleteParams{promptId=$promptId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPage.kt index 43cda3c0..54e69368 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.PromptService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all prompts. The prompts are sorted by creation date, with the most recently-created + * prompts coming first + */ class PromptListPage private constructor( private val promptsService: PromptService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is PromptListPage && - this.promptsService == other.promptsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is PromptListPage && promptsService == other.promptsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - promptsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(promptsService, params, response) /* spotless:on */ override fun toString() = "PromptListPage{promptsService=$promptsService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(promptsService: PromptService, params: PromptListParams, response: Response) = - PromptListPage( - promptsService, - params, - response, - ) + PromptListPage(promptsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "PromptListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [PromptListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: PromptListPage, - ) : Iterable { + class AutoPager(private val firstPage: PromptListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPageAsync.kt index 31a7d456..d360b8a7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.PromptServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all prompts. The prompts are sorted by creation date, with the most recently-created + * prompts coming first + */ class PromptListPageAsync private constructor( private val promptsService: PromptServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is PromptListPageAsync && - this.promptsService == other.promptsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is PromptListPageAsync && promptsService == other.promptsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - promptsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(promptsService, params, response) /* spotless:on */ override fun toString() = "PromptListPageAsync{promptsService=$promptsService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(promptsService: PromptServiceAsync, params: PromptListParams, response: Response) = - PromptListPageAsync( - promptsService, - params, - response, - ) + PromptListPageAsync(promptsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "PromptListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [PromptListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: PromptListPageAsync, - ) { + class AutoPager(private val firstPage: PromptListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Prompt) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListParams.kt index 9dfce694..d5c704fa 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all prompts. The prompts are sorted by creation date, with the most recently-created + * prompts coming first + */ class PromptListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, @@ -32,102 +38,106 @@ constructor( private val slug: String?, private val startingAfter: String?, private val version: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Project id */ fun projectId(): Optional = Optional.ofNullable(projectId) + /** Name of the project to search for */ fun projectName(): Optional = Optional.ofNullable(projectName) + /** Name of the prompt to search for */ fun promptName(): Optional = Optional.ofNullable(promptName) + /** Retrieve prompt with a specific slug */ fun slug(): Optional = Optional.ofNullable(slug) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) + /** + * Retrieve prompt at a specific version. + * + * The version id can either be a transaction id (e.g. '1000192656880881099') or a version + * identifier (e.g. '81cd05ee665fdfb3'). + */ fun version(): Optional = Optional.ofNullable(version) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.projectId?.let { params.put("project_id", listOf(it.toString())) } - this.projectName?.let { params.put("project_name", listOf(it.toString())) } - this.promptName?.let { params.put("prompt_name", listOf(it.toString())) } - this.slug?.let { params.put("slug", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - this.version?.let { params.put("version", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.projectId == other.projectId && - this.projectName == other.projectName && - this.promptName == other.promptName && - this.slug == other.slug && - this.startingAfter == other.startingAfter && - this.version == other.version && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - projectId, - projectName, - promptName, - slug, - startingAfter, - version, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "PromptListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, promptName=$promptName, slug=$slug, startingAfter=$startingAfter, version=$version, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + projectId?.let { put("project_id", it) } + projectName?.let { put("project_name", it) } + promptName?.let { put("prompt_name", it) } + slug?.let { put("slug", it) } + startingAfter?.let { put("starting_after", it) } + version?.let { put("version", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): PromptListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [PromptListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null @@ -139,23 +149,23 @@ constructor( private var slug: String? = null private var startingAfter: String? = null private var version: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(promptListParams: PromptListParams) = apply { - this.endingBefore = promptListParams.endingBefore - this.ids = promptListParams.ids - this.limit = promptListParams.limit - this.orgName = promptListParams.orgName - this.projectId = promptListParams.projectId - this.projectName = promptListParams.projectName - this.promptName = promptListParams.promptName - this.slug = promptListParams.slug - this.startingAfter = promptListParams.startingAfter - this.version = promptListParams.version - additionalQueryParams(promptListParams.additionalQueryParams) - additionalHeaders(promptListParams.additionalHeaders) + endingBefore = promptListParams.endingBefore + ids = promptListParams.ids + limit = promptListParams.limit + orgName = promptListParams.orgName + projectId = promptListParams.projectId + projectName = promptListParams.projectName + promptName = promptListParams.promptName + slug = promptListParams.slug + startingAfter = promptListParams.startingAfter + version = promptListParams.version + additionalHeaders = promptListParams.additionalHeaders.toBuilder() + additionalQueryParams = promptListParams.additionalQueryParams.toBuilder() } /** @@ -165,43 +175,68 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Project id */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String?) = apply { this.projectId = projectId } + + /** Alias for calling [Builder.projectId] with `projectId.orElse(null)`. */ + fun projectId(projectId: Optional) = projectId(projectId.getOrNull()) /** Name of the project to search for */ - fun projectName(projectName: String) = apply { this.projectName = projectName } + fun projectName(projectName: String?) = apply { this.projectName = projectName } + + /** Alias for calling [Builder.projectName] with `projectName.orElse(null)`. */ + fun projectName(projectName: Optional) = projectName(projectName.getOrNull()) /** Name of the prompt to search for */ - fun promptName(promptName: String) = apply { this.promptName = promptName } + fun promptName(promptName: String?) = apply { this.promptName = promptName } + + /** Alias for calling [Builder.promptName] with `promptName.orElse(null)`. */ + fun promptName(promptName: Optional) = promptName(promptName.getOrNull()) /** Retrieve prompt with a specific slug */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String?) = apply { this.slug = slug } + + /** Alias for calling [Builder.slug] with `slug.orElse(null)`. */ + fun slug(slug: Optional) = slug(slug.getOrNull()) /** * Pagination cursor id. @@ -210,7 +245,11 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } + + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) /** * Retrieve prompt at a specific version. @@ -218,48 +257,114 @@ constructor( * The version id can either be a transaction id (e.g. '1000192656880881099') or a version * identifier (e.g. '81cd05ee665fdfb3'). */ - fun version(version: String) = apply { this.version = version } + fun version(version: String?) = apply { this.version = version } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.version] with `version.orElse(null)`. */ + fun version(version: Optional) = version(version.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [PromptListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): PromptListParams = PromptListParams( endingBefore, @@ -272,11 +377,15 @@ constructor( slug, startingAfter, version, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -286,8 +395,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -310,35 +417,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -347,21 +442,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -373,12 +479,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -389,4 +495,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && projectId == other.projectId && projectName == other.projectName && promptName == other.promptName && slug == other.slug && startingAfter == other.startingAfter && version == other.version && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, projectId, projectName, promptName, slug, startingAfter, version, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "PromptListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, projectId=$projectId, projectName=$projectName, promptName=$promptName, slug=$slug, startingAfter=$startingAfter, version=$version, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptOptions.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptOptions.kt new file mode 100644 index 00000000..c13395bf --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptOptions.kt @@ -0,0 +1,4601 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.BaseDeserializer +import com.braintrustdata.api.core.BaseSerializer +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.getOrThrow +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +@NoAutoDetect +class PromptOptions +@JsonCreator +private constructor( + @JsonProperty("model") @ExcludeMissing private val model: JsonField = JsonMissing.of(), + @JsonProperty("params") + @ExcludeMissing + private val params: JsonField = JsonMissing.of(), + @JsonProperty("position") + @ExcludeMissing + private val position: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun model(): Optional = Optional.ofNullable(model.getNullable("model")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun params(): Optional = Optional.ofNullable(params.getNullable("params")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun position(): Optional = Optional.ofNullable(position.getNullable("position")) + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [params]. + * + * Unlike [params], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("params") @ExcludeMissing fun _params(): JsonField = params + + /** + * Returns the raw JSON value of [position]. + * + * Unlike [position], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("position") @ExcludeMissing fun _position(): JsonField = position + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): PromptOptions = apply { + if (validated) { + return@apply + } + + model() + params().ifPresent { it.validate() } + position() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [PromptOptions]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PromptOptions]. */ + class Builder internal constructor() { + + private var model: JsonField = JsonMissing.of() + private var params: JsonField = JsonMissing.of() + private var position: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(promptOptions: PromptOptions) = apply { + model = promptOptions.model + params = promptOptions.params + position = promptOptions.position + additionalProperties = promptOptions.additionalProperties.toMutableMap() + } + + fun model(model: String) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + fun params(params: Params) = params(JsonField.of(params)) + + /** + * Sets [Builder.params] to an arbitrary JSON value. + * + * You should usually call [Builder.params] with a well-typed [Params] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun params(params: JsonField) = apply { this.params = params } + + /** Alias for calling [params] with `Params.ofOpenAIModel(openaiModel)`. */ + fun params(openaiModel: Params.OpenAIModelParams) = + params(Params.ofOpenAIModel(openaiModel)) + + /** Alias for calling [params] with `Params.ofAnthropicModel(anthropicModel)`. */ + fun params(anthropicModel: Params.AnthropicModelParams) = + params(Params.ofAnthropicModel(anthropicModel)) + + /** Alias for calling [params] with `Params.ofGoogleModel(googleModel)`. */ + fun params(googleModel: Params.GoogleModelParams) = + params(Params.ofGoogleModel(googleModel)) + + /** Alias for calling [params] with `Params.ofWindowAiModel(windowAiModel)`. */ + fun params(windowAiModel: Params.WindowAiModelParams) = + params(Params.ofWindowAiModel(windowAiModel)) + + /** Alias for calling [params] with `Params.ofJsCompletion(jsCompletion)`. */ + fun params(jsCompletion: Params.JsCompletionParams) = + params(Params.ofJsCompletion(jsCompletion)) + + fun position(position: String) = position(JsonField.of(position)) + + /** + * Sets [Builder.position] to an arbitrary JSON value. + * + * You should usually call [Builder.position] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun position(position: JsonField) = apply { this.position = position } + + 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 [PromptOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PromptOptions = + PromptOptions(model, params, position, additionalProperties.toImmutable()) + } + + @JsonDeserialize(using = Params.Deserializer::class) + @JsonSerialize(using = Params.Serializer::class) + class Params + private constructor( + private val openaiModel: OpenAIModelParams? = null, + private val anthropicModel: AnthropicModelParams? = null, + private val googleModel: GoogleModelParams? = null, + private val windowAiModel: WindowAiModelParams? = null, + private val jsCompletion: JsCompletionParams? = null, + private val _json: JsonValue? = null, + ) { + + fun openaiModel(): Optional = Optional.ofNullable(openaiModel) + + fun anthropicModel(): Optional = Optional.ofNullable(anthropicModel) + + fun googleModel(): Optional = Optional.ofNullable(googleModel) + + fun windowAiModel(): Optional = Optional.ofNullable(windowAiModel) + + fun jsCompletion(): Optional = Optional.ofNullable(jsCompletion) + + fun isOpenAIModel(): Boolean = openaiModel != null + + fun isAnthropicModel(): Boolean = anthropicModel != null + + fun isGoogleModel(): Boolean = googleModel != null + + fun isWindowAiModel(): Boolean = windowAiModel != null + + fun isJsCompletion(): Boolean = jsCompletion != null + + fun asOpenAIModel(): OpenAIModelParams = openaiModel.getOrThrow("openaiModel") + + fun asAnthropicModel(): AnthropicModelParams = anthropicModel.getOrThrow("anthropicModel") + + fun asGoogleModel(): GoogleModelParams = googleModel.getOrThrow("googleModel") + + fun asWindowAiModel(): WindowAiModelParams = windowAiModel.getOrThrow("windowAiModel") + + fun asJsCompletion(): JsCompletionParams = jsCompletion.getOrThrow("jsCompletion") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + openaiModel != null -> visitor.visitOpenAIModel(openaiModel) + anthropicModel != null -> visitor.visitAnthropicModel(anthropicModel) + googleModel != null -> visitor.visitGoogleModel(googleModel) + windowAiModel != null -> visitor.visitWindowAiModel(windowAiModel) + jsCompletion != null -> visitor.visitJsCompletion(jsCompletion) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): Params = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitOpenAIModel(openaiModel: OpenAIModelParams) { + openaiModel.validate() + } + + override fun visitAnthropicModel(anthropicModel: AnthropicModelParams) { + anthropicModel.validate() + } + + override fun visitGoogleModel(googleModel: GoogleModelParams) { + googleModel.validate() + } + + override fun visitWindowAiModel(windowAiModel: WindowAiModelParams) { + windowAiModel.validate() + } + + override fun visitJsCompletion(jsCompletion: JsCompletionParams) { + jsCompletion.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Params && openaiModel == other.openaiModel && anthropicModel == other.anthropicModel && googleModel == other.googleModel && windowAiModel == other.windowAiModel && jsCompletion == other.jsCompletion /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(openaiModel, anthropicModel, googleModel, windowAiModel, jsCompletion) /* spotless:on */ + + override fun toString(): String = + when { + openaiModel != null -> "Params{openaiModel=$openaiModel}" + anthropicModel != null -> "Params{anthropicModel=$anthropicModel}" + googleModel != null -> "Params{googleModel=$googleModel}" + windowAiModel != null -> "Params{windowAiModel=$windowAiModel}" + jsCompletion != null -> "Params{jsCompletion=$jsCompletion}" + _json != null -> "Params{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Params") + } + + companion object { + + @JvmStatic + fun ofOpenAIModel(openaiModel: OpenAIModelParams) = Params(openaiModel = openaiModel) + + @JvmStatic + fun ofAnthropicModel(anthropicModel: AnthropicModelParams) = + Params(anthropicModel = anthropicModel) + + @JvmStatic + fun ofGoogleModel(googleModel: GoogleModelParams) = Params(googleModel = googleModel) + + @JvmStatic + fun ofWindowAiModel(windowAiModel: WindowAiModelParams) = + Params(windowAiModel = windowAiModel) + + @JvmStatic + fun ofJsCompletion(jsCompletion: JsCompletionParams) = + Params(jsCompletion = jsCompletion) + } + + /** An interface that defines how to map each variant of [Params] to a value of type [T]. */ + interface Visitor { + + fun visitOpenAIModel(openaiModel: OpenAIModelParams): T + + fun visitAnthropicModel(anthropicModel: AnthropicModelParams): T + + fun visitGoogleModel(googleModel: GoogleModelParams): T + + fun visitWindowAiModel(windowAiModel: WindowAiModelParams): T + + fun visitJsCompletion(jsCompletion: JsCompletionParams): T + + /** + * Maps an unknown variant of [Params] to a value of type [T]. + * + * An instance of [Params] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Params: $json") + } + } + + internal class Deserializer : BaseDeserializer(Params::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Params { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Params(openaiModel = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Params(anthropicModel = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Params(googleModel = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Params(windowAiModel = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Params(jsCompletion = it, _json = json) + } + + return Params(_json = json) + } + } + + internal class Serializer : BaseSerializer(Params::class) { + + override fun serialize( + value: Params, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.openaiModel != null -> generator.writeObject(value.openaiModel) + value.anthropicModel != null -> generator.writeObject(value.anthropicModel) + value.googleModel != null -> generator.writeObject(value.googleModel) + value.windowAiModel != null -> generator.writeObject(value.windowAiModel) + value.jsCompletion != null -> generator.writeObject(value.jsCompletion) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Params") + } + } + } + + @NoAutoDetect + class OpenAIModelParams + @JsonCreator + private constructor( + @JsonProperty("frequency_penalty") + @ExcludeMissing + private val frequencyPenalty: JsonField = JsonMissing.of(), + @JsonProperty("function_call") + @ExcludeMissing + private val functionCall: JsonField = JsonMissing.of(), + @JsonProperty("max_completion_tokens") + @ExcludeMissing + private val maxCompletionTokens: JsonField = JsonMissing.of(), + @JsonProperty("max_tokens") + @ExcludeMissing + private val maxTokens: JsonField = JsonMissing.of(), + @JsonProperty("n") @ExcludeMissing private val n: JsonField = JsonMissing.of(), + @JsonProperty("presence_penalty") + @ExcludeMissing + private val presencePenalty: JsonField = JsonMissing.of(), + @JsonProperty("reasoning_effort") + @ExcludeMissing + private val reasoningEffort: JsonField = JsonMissing.of(), + @JsonProperty("response_format") + @ExcludeMissing + private val responseFormat: JsonField = JsonMissing.of(), + @JsonProperty("stop") + @ExcludeMissing + private val stop: JsonField> = JsonMissing.of(), + @JsonProperty("temperature") + @ExcludeMissing + private val temperature: JsonField = JsonMissing.of(), + @JsonProperty("tool_choice") + @ExcludeMissing + private val toolChoice: JsonField = JsonMissing.of(), + @JsonProperty("top_p") + @ExcludeMissing + private val topP: JsonField = JsonMissing.of(), + @JsonProperty("use_cache") + @ExcludeMissing + private val useCache: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun frequencyPenalty(): Optional = + Optional.ofNullable(frequencyPenalty.getNullable("frequency_penalty")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun functionCall(): Optional = + Optional.ofNullable(functionCall.getNullable("function_call")) + + /** + * The successor to max_tokens + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun maxCompletionTokens(): Optional = + Optional.ofNullable(maxCompletionTokens.getNullable("max_completion_tokens")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun maxTokens(): Optional = + Optional.ofNullable(maxTokens.getNullable("max_tokens")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun n(): Optional = Optional.ofNullable(n.getNullable("n")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun presencePenalty(): Optional = + Optional.ofNullable(presencePenalty.getNullable("presence_penalty")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun reasoningEffort(): Optional = + Optional.ofNullable(reasoningEffort.getNullable("reasoning_effort")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun responseFormat(): Optional = + Optional.ofNullable(responseFormat.getNullable("response_format")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun stop(): Optional> = Optional.ofNullable(stop.getNullable("stop")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun temperature(): Optional = + Optional.ofNullable(temperature.getNullable("temperature")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun toolChoice(): Optional = + Optional.ofNullable(toolChoice.getNullable("tool_choice")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topP(): Optional = Optional.ofNullable(topP.getNullable("top_p")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun useCache(): Optional = + Optional.ofNullable(useCache.getNullable("use_cache")) + + /** + * Returns the raw JSON value of [frequencyPenalty]. + * + * Unlike [frequencyPenalty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("frequency_penalty") + @ExcludeMissing + fun _frequencyPenalty(): JsonField = frequencyPenalty + + /** + * Returns the raw JSON value of [functionCall]. + * + * Unlike [functionCall], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_call") + @ExcludeMissing + fun _functionCall(): JsonField = functionCall + + /** + * Returns the raw JSON value of [maxCompletionTokens]. + * + * Unlike [maxCompletionTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("max_completion_tokens") + @ExcludeMissing + fun _maxCompletionTokens(): JsonField = maxCompletionTokens + + /** + * Returns the raw JSON value of [maxTokens]. + * + * Unlike [maxTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_tokens") + @ExcludeMissing + fun _maxTokens(): JsonField = maxTokens + + /** + * Returns the raw JSON value of [n]. + * + * Unlike [n], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("n") @ExcludeMissing fun _n(): JsonField = n + + /** + * Returns the raw JSON value of [presencePenalty]. + * + * Unlike [presencePenalty], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("presence_penalty") + @ExcludeMissing + fun _presencePenalty(): JsonField = presencePenalty + + /** + * Returns the raw JSON value of [reasoningEffort]. + * + * Unlike [reasoningEffort], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("reasoning_effort") + @ExcludeMissing + fun _reasoningEffort(): JsonField = reasoningEffort + + /** + * Returns the raw JSON value of [responseFormat]. + * + * Unlike [responseFormat], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("response_format") + @ExcludeMissing + fun _responseFormat(): JsonField = responseFormat + + /** + * Returns the raw JSON value of [stop]. + * + * Unlike [stop], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stop") @ExcludeMissing fun _stop(): JsonField> = stop + + /** + * Returns the raw JSON value of [temperature]. + * + * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("temperature") + @ExcludeMissing + fun _temperature(): JsonField = temperature + + /** + * Returns the raw JSON value of [toolChoice]. + * + * Unlike [toolChoice], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("tool_choice") + @ExcludeMissing + fun _toolChoice(): JsonField = toolChoice + + /** + * Returns the raw JSON value of [topP]. + * + * Unlike [topP], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("top_p") @ExcludeMissing fun _topP(): JsonField = topP + + /** + * Returns the raw JSON value of [useCache]. + * + * Unlike [useCache], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("use_cache") + @ExcludeMissing + fun _useCache(): JsonField = useCache + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): OpenAIModelParams = apply { + if (validated) { + return@apply + } + + frequencyPenalty() + functionCall().ifPresent { it.validate() } + maxCompletionTokens() + maxTokens() + n() + presencePenalty() + reasoningEffort() + responseFormat().ifPresent { it.validate() } + stop() + temperature() + toolChoice().ifPresent { it.validate() } + topP() + useCache() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [OpenAIModelParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [OpenAIModelParams]. */ + class Builder internal constructor() { + + private var frequencyPenalty: JsonField = JsonMissing.of() + private var functionCall: JsonField = JsonMissing.of() + private var maxCompletionTokens: JsonField = JsonMissing.of() + private var maxTokens: JsonField = JsonMissing.of() + private var n: JsonField = JsonMissing.of() + private var presencePenalty: JsonField = JsonMissing.of() + private var reasoningEffort: JsonField = JsonMissing.of() + private var responseFormat: JsonField = JsonMissing.of() + private var stop: JsonField>? = null + private var temperature: JsonField = JsonMissing.of() + private var toolChoice: JsonField = JsonMissing.of() + private var topP: JsonField = JsonMissing.of() + private var useCache: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(openaiModelParams: OpenAIModelParams) = apply { + frequencyPenalty = openaiModelParams.frequencyPenalty + functionCall = openaiModelParams.functionCall + maxCompletionTokens = openaiModelParams.maxCompletionTokens + maxTokens = openaiModelParams.maxTokens + n = openaiModelParams.n + presencePenalty = openaiModelParams.presencePenalty + reasoningEffort = openaiModelParams.reasoningEffort + responseFormat = openaiModelParams.responseFormat + stop = openaiModelParams.stop.map { it.toMutableList() } + temperature = openaiModelParams.temperature + toolChoice = openaiModelParams.toolChoice + topP = openaiModelParams.topP + useCache = openaiModelParams.useCache + additionalProperties = openaiModelParams.additionalProperties.toMutableMap() + } + + fun frequencyPenalty(frequencyPenalty: Double) = + frequencyPenalty(JsonField.of(frequencyPenalty)) + + /** + * Sets [Builder.frequencyPenalty] to an arbitrary JSON value. + * + * You should usually call [Builder.frequencyPenalty] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun frequencyPenalty(frequencyPenalty: JsonField) = apply { + this.frequencyPenalty = frequencyPenalty + } + + fun functionCall(functionCall: FunctionCall) = + functionCall(JsonField.of(functionCall)) + + /** + * Sets [Builder.functionCall] to an arbitrary JSON value. + * + * You should usually call [Builder.functionCall] with a well-typed [FunctionCall] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun functionCall(functionCall: JsonField) = apply { + this.functionCall = functionCall + } + + /** + * Alias for calling [functionCall] with + * `FunctionCall.ofUnionMember0(unionMember0)`. + */ + fun functionCall(unionMember0: FunctionCall.UnionMember0) = + functionCall(FunctionCall.ofUnionMember0(unionMember0)) + + /** Alias for calling [functionCall] with `FunctionCall.ofFunction(function)`. */ + fun functionCall(function: FunctionCall.Function) = + functionCall(FunctionCall.ofFunction(function)) + + /** The successor to max_tokens */ + fun maxCompletionTokens(maxCompletionTokens: Double) = + maxCompletionTokens(JsonField.of(maxCompletionTokens)) + + /** + * Sets [Builder.maxCompletionTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.maxCompletionTokens] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun maxCompletionTokens(maxCompletionTokens: JsonField) = apply { + this.maxCompletionTokens = maxCompletionTokens + } + + fun maxTokens(maxTokens: Double) = maxTokens(JsonField.of(maxTokens)) + + /** + * Sets [Builder.maxTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.maxTokens] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun maxTokens(maxTokens: JsonField) = apply { this.maxTokens = maxTokens } + + fun n(n: Double) = n(JsonField.of(n)) + + /** + * Sets [Builder.n] to an arbitrary JSON value. + * + * You should usually call [Builder.n] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun n(n: JsonField) = apply { this.n = n } + + fun presencePenalty(presencePenalty: Double) = + presencePenalty(JsonField.of(presencePenalty)) + + /** + * Sets [Builder.presencePenalty] to an arbitrary JSON value. + * + * You should usually call [Builder.presencePenalty] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun presencePenalty(presencePenalty: JsonField) = apply { + this.presencePenalty = presencePenalty + } + + fun reasoningEffort(reasoningEffort: ReasoningEffort) = + reasoningEffort(JsonField.of(reasoningEffort)) + + /** + * Sets [Builder.reasoningEffort] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoningEffort] with a well-typed + * [ReasoningEffort] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun reasoningEffort(reasoningEffort: JsonField) = apply { + this.reasoningEffort = reasoningEffort + } + + fun responseFormat(responseFormat: ResponseFormat?) = + responseFormat(JsonField.ofNullable(responseFormat)) + + /** + * Alias for calling [Builder.responseFormat] with `responseFormat.orElse(null)`. + */ + fun responseFormat(responseFormat: Optional) = + responseFormat(responseFormat.getOrNull()) + + /** + * Sets [Builder.responseFormat] to an arbitrary JSON value. + * + * You should usually call [Builder.responseFormat] with a well-typed + * [ResponseFormat] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun responseFormat(responseFormat: JsonField) = apply { + this.responseFormat = responseFormat + } + + /** + * Alias for calling [responseFormat] with + * `ResponseFormat.ofJsonObject(jsonObject)`. + */ + fun responseFormat(jsonObject: ResponseFormat.JsonObject) = + responseFormat(ResponseFormat.ofJsonObject(jsonObject)) + + /** + * Alias for calling [responseFormat] with + * `ResponseFormat.ofJsonSchema(jsonSchema)`. + */ + fun responseFormat(jsonSchema: ResponseFormat.JsonSchema) = + responseFormat(ResponseFormat.ofJsonSchema(jsonSchema)) + + /** Alias for calling [responseFormat] with `ResponseFormat.ofText(text)`. */ + fun responseFormat(text: ResponseFormat.Text) = + responseFormat(ResponseFormat.ofText(text)) + + fun stop(stop: List) = stop(JsonField.of(stop)) + + /** + * Sets [Builder.stop] to an arbitrary JSON value. + * + * You should usually call [Builder.stop] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun stop(stop: JsonField>) = apply { + this.stop = stop.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.stop]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addStop(stop: String) = apply { + this.stop = + (this.stop ?: JsonField.of(mutableListOf())).also { + checkKnown("stop", it).add(stop) + } + } + + fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + + /** + * Sets [Builder.temperature] to an arbitrary JSON value. + * + * You should usually call [Builder.temperature] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun temperature(temperature: JsonField) = apply { + this.temperature = temperature + } + + fun toolChoice(toolChoice: ToolChoice) = toolChoice(JsonField.of(toolChoice)) + + /** + * Sets [Builder.toolChoice] to an arbitrary JSON value. + * + * You should usually call [Builder.toolChoice] with a well-typed [ToolChoice] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun toolChoice(toolChoice: JsonField) = apply { + this.toolChoice = toolChoice + } + + /** + * Alias for calling [toolChoice] with `ToolChoice.ofUnionMember0(unionMember0)`. + */ + fun toolChoice(unionMember0: ToolChoice.UnionMember0) = + toolChoice(ToolChoice.ofUnionMember0(unionMember0)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofFunction(function)`. */ + fun toolChoice(function: ToolChoice.Function) = + toolChoice(ToolChoice.ofFunction(function)) + + fun topP(topP: Double) = topP(JsonField.of(topP)) + + /** + * Sets [Builder.topP] to an arbitrary JSON value. + * + * You should usually call [Builder.topP] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topP(topP: JsonField) = apply { this.topP = topP } + + fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + + /** + * Sets [Builder.useCache] to an arbitrary JSON value. + * + * You should usually call [Builder.useCache] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + + 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 [OpenAIModelParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): OpenAIModelParams = + OpenAIModelParams( + frequencyPenalty, + functionCall, + maxCompletionTokens, + maxTokens, + n, + presencePenalty, + reasoningEffort, + responseFormat, + (stop ?: JsonMissing.of()).map { it.toImmutable() }, + temperature, + toolChoice, + topP, + useCache, + additionalProperties.toImmutable(), + ) + } + + @JsonDeserialize(using = FunctionCall.Deserializer::class) + @JsonSerialize(using = FunctionCall.Serializer::class) + class FunctionCall + private constructor( + private val unionMember0: UnionMember0? = null, + private val function: Function? = null, + private val _json: JsonValue? = null, + ) { + + fun unionMember0(): Optional = Optional.ofNullable(unionMember0) + + fun function(): Optional = Optional.ofNullable(function) + + fun isUnionMember0(): Boolean = unionMember0 != null + + fun isFunction(): Boolean = function != null + + fun asUnionMember0(): UnionMember0 = unionMember0.getOrThrow("unionMember0") + + fun asFunction(): Function = function.getOrThrow("function") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + unionMember0 != null -> visitor.visitUnionMember0(unionMember0) + function != null -> visitor.visitFunction(function) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): FunctionCall = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) {} + + override fun visitFunction(function: Function) { + function.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionCall && unionMember0 == other.unionMember0 && function == other.function /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(unionMember0, function) /* spotless:on */ + + override fun toString(): String = + when { + unionMember0 != null -> "FunctionCall{unionMember0=$unionMember0}" + function != null -> "FunctionCall{function=$function}" + _json != null -> "FunctionCall{_unknown=$_json}" + else -> throw IllegalStateException("Invalid FunctionCall") + } + + companion object { + + @JvmStatic + fun ofUnionMember0(unionMember0: UnionMember0) = + FunctionCall(unionMember0 = unionMember0) + + @JvmStatic + fun ofFunction(function: Function) = FunctionCall(function = function) + } + + /** + * An interface that defines how to map each variant of [FunctionCall] to a value of + * type [T]. + */ + interface Visitor { + + fun visitUnionMember0(unionMember0: UnionMember0): T + + fun visitFunction(function: Function): T + + /** + * Maps an unknown variant of [FunctionCall] to a value of type [T]. + * + * An instance of [FunctionCall] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown FunctionCall: $json") + } + } + + internal class Deserializer : BaseDeserializer(FunctionCall::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): FunctionCall { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef())?.let { + return FunctionCall(unionMember0 = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return FunctionCall(function = it, _json = json) + } + + return FunctionCall(_json = json) + } + } + + internal class Serializer : BaseSerializer(FunctionCall::class) { + + override fun serialize( + value: FunctionCall, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.unionMember0 != null -> generator.writeObject(value.unionMember0) + value.function != null -> generator.writeObject(value.function) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid FunctionCall") + } + } + } + + class UnionMember0 + @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 AUTO = of("auto") + + @JvmField val NONE = of("none") + + @JvmStatic fun of(value: String) = UnionMember0(JsonField.of(value)) + } + + /** An enum containing [UnionMember0]'s known values. */ + enum class Known { + AUTO, + NONE, + } + + /** + * An enum containing [UnionMember0]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [UnionMember0] 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 { + AUTO, + NONE, + /** + * An enum member indicating that [UnionMember0] 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) { + AUTO -> Value.AUTO + NONE -> Value.NONE + 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 BraintrustInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + AUTO -> Known.AUTO + NONE -> Known.NONE + else -> + throw BraintrustInvalidDataException("Unknown UnionMember0: $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 BraintrustInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is UnionMember0 && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + @NoAutoDetect + class Function + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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") + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Function = apply { + if (validated) { + return@apply + } + + name() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Function]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(function: Function) = apply { + name = function.name + additionalProperties = function.additionalProperties.toMutableMap() + } + + 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 } + + 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 [Function]. + * + * 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(): Function = + Function( + checkRequired("name", name), + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{name=$name, additionalProperties=$additionalProperties}" + } + } + + class ReasoningEffort + @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 LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmStatic fun of(value: String) = ReasoningEffort(JsonField.of(value)) + } + + /** An enum containing [ReasoningEffort]'s known values. */ + enum class Known { + LOW, + MEDIUM, + HIGH, + } + + /** + * An enum containing [ReasoningEffort]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [ReasoningEffort] 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 { + LOW, + MEDIUM, + HIGH, + /** + * An enum member indicating that [ReasoningEffort] 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) { + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + 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 BraintrustInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + else -> + throw BraintrustInvalidDataException("Unknown ReasoningEffort: $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 BraintrustInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ReasoningEffort && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + @JsonDeserialize(using = ResponseFormat.Deserializer::class) + @JsonSerialize(using = ResponseFormat.Serializer::class) + class ResponseFormat + private constructor( + private val jsonObject: JsonObject? = null, + private val jsonSchema: JsonSchema? = null, + private val text: Text? = null, + private val _json: JsonValue? = null, + ) { + + fun jsonObject(): Optional = Optional.ofNullable(jsonObject) + + fun jsonSchema(): Optional = Optional.ofNullable(jsonSchema) + + fun text(): Optional = Optional.ofNullable(text) + + fun isJsonObject(): Boolean = jsonObject != null + + fun isJsonSchema(): Boolean = jsonSchema != null + + fun isText(): Boolean = text != null + + fun asJsonObject(): JsonObject = jsonObject.getOrThrow("jsonObject") + + fun asJsonSchema(): JsonSchema = jsonSchema.getOrThrow("jsonSchema") + + fun asText(): Text = text.getOrThrow("text") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + jsonObject != null -> visitor.visitJsonObject(jsonObject) + jsonSchema != null -> visitor.visitJsonSchema(jsonSchema) + text != null -> visitor.visitText(text) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): ResponseFormat = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitJsonObject(jsonObject: JsonObject) { + jsonObject.validate() + } + + override fun visitJsonSchema(jsonSchema: JsonSchema) { + jsonSchema.validate() + } + + override fun visitText(text: Text) { + text.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ResponseFormat && jsonObject == other.jsonObject && jsonSchema == other.jsonSchema && text == other.text /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(jsonObject, jsonSchema, text) /* spotless:on */ + + override fun toString(): String = + when { + jsonObject != null -> "ResponseFormat{jsonObject=$jsonObject}" + jsonSchema != null -> "ResponseFormat{jsonSchema=$jsonSchema}" + text != null -> "ResponseFormat{text=$text}" + _json != null -> "ResponseFormat{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseFormat") + } + + companion object { + + @JvmStatic + fun ofJsonObject(jsonObject: JsonObject) = + ResponseFormat(jsonObject = jsonObject) + + @JvmStatic + fun ofJsonSchema(jsonSchema: JsonSchema) = + ResponseFormat(jsonSchema = jsonSchema) + + @JvmStatic fun ofText(text: Text) = ResponseFormat(text = text) + } + + /** + * An interface that defines how to map each variant of [ResponseFormat] to a value + * of type [T]. + */ + interface Visitor { + + fun visitJsonObject(jsonObject: JsonObject): T + + fun visitJsonSchema(jsonSchema: JsonSchema): T + + fun visitText(text: Text): T + + /** + * Maps an unknown variant of [ResponseFormat] to a value of type [T]. + * + * An instance of [ResponseFormat] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown ResponseFormat: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ResponseFormat::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseFormat { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return ResponseFormat(jsonObject = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return ResponseFormat(jsonSchema = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return ResponseFormat(text = it, _json = json) + } + + return ResponseFormat(_json = json) + } + } + + internal class Serializer : BaseSerializer(ResponseFormat::class) { + + override fun serialize( + value: ResponseFormat, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.jsonObject != null -> generator.writeObject(value.jsonObject) + value.jsonSchema != null -> generator.writeObject(value.jsonSchema) + value.text != null -> generator.writeObject(value.text) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseFormat") + } + } + } + + @NoAutoDetect + class JsonObject + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): JsonObject = apply { + if (validated) { + return@apply + } + + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [JsonObject]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [JsonObject]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(jsonObject: JsonObject) = apply { + type = jsonObject.type + additionalProperties = jsonObject.additionalProperties.toMutableMap() + } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [JsonObject]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): JsonObject = + JsonObject( + checkRequired("type", type), + additionalProperties.toImmutable(), + ) + } + + class Type + @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 JSON_OBJECT = of("json_object") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + JSON_OBJECT + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { + JSON_OBJECT, + /** + * An enum member indicating that [Type] 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) { + JSON_OBJECT -> Value.JSON_OBJECT + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + JSON_OBJECT -> Known.JSON_OBJECT + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is JsonObject && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "JsonObject{type=$type, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class JsonSchema + @JsonCreator + private constructor( + @JsonProperty("json_schema") + @ExcludeMissing + private val jsonSchema: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 jsonSchema(): InnerJsonSchema = jsonSchema.getRequired("json_schema") + + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [jsonSchema]. + * + * Unlike [jsonSchema], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("json_schema") + @ExcludeMissing + fun _jsonSchema(): JsonField = jsonSchema + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): JsonSchema = apply { + if (validated) { + return@apply + } + + jsonSchema().validate() + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [JsonSchema]. + * + * The following fields are required: + * ```java + * .jsonSchema() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [JsonSchema]. */ + class Builder internal constructor() { + + private var jsonSchema: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(jsonSchema: JsonSchema) = apply { + this.jsonSchema = jsonSchema.jsonSchema + type = jsonSchema.type + additionalProperties = jsonSchema.additionalProperties.toMutableMap() + } + + fun jsonSchema(jsonSchema: InnerJsonSchema) = + jsonSchema(JsonField.of(jsonSchema)) + + /** + * Sets [Builder.jsonSchema] to an arbitrary JSON value. + * + * You should usually call [Builder.jsonSchema] with a well-typed + * [InnerJsonSchema] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun jsonSchema(jsonSchema: JsonField) = apply { + this.jsonSchema = jsonSchema + } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [JsonSchema]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .jsonSchema() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): JsonSchema = + JsonSchema( + checkRequired("jsonSchema", jsonSchema), + checkRequired("type", type), + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class InnerJsonSchema + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("schema") + @ExcludeMissing + private val schema: JsonField = JsonMissing.of(), + @JsonProperty("strict") + @ExcludeMissing + private val strict: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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") + + /** + * @throws BraintrustInvalidDataException if the JSON field has an + * unexpected type (e.g. if the server responded with an unexpected + * value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an + * unexpected type (e.g. if the server responded with an unexpected + * value). + */ + fun schema(): Optional = + Optional.ofNullable(schema.getNullable("schema")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an + * unexpected type (e.g. if the server responded with an unexpected + * value). + */ + fun strict(): Optional = + Optional.ofNullable(strict.getNullable("strict")) + + /** + * 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 [schema]. + * + * Unlike [schema], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("schema") + @ExcludeMissing + fun _schema(): JsonField = schema + + /** + * Returns the raw JSON value of [strict]. + * + * Unlike [strict], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("strict") + @ExcludeMissing + fun _strict(): JsonField = strict + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InnerJsonSchema = apply { + if (validated) { + return@apply + } + + name() + description() + schema().ifPresent { it.validate() } + strict() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [InnerJsonSchema]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InnerJsonSchema]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var schema: JsonField = JsonMissing.of() + private var strict: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(innerJsonSchema: InnerJsonSchema) = apply { + name = innerJsonSchema.name + description = innerJsonSchema.description + schema = innerJsonSchema.schema + strict = innerJsonSchema.strict + additionalProperties = + innerJsonSchema.additionalProperties.toMutableMap() + } + + 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 } + + fun description(description: String) = + description(JsonField.of(description)) + + /** + * 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 + } + + fun schema(schema: Schema) = schema(JsonField.of(schema)) + + /** + * Sets [Builder.schema] to an arbitrary JSON value. + * + * You should usually call [Builder.schema] with a well-typed [Schema] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun schema(schema: JsonField) = apply { this.schema = schema } + + /** Alias for calling [schema] with `Schema.ofObject(object_)`. */ + fun schema(object_: Schema.Object) = schema(Schema.ofObject(object_)) + + /** Alias for calling [schema] with `Schema.ofString(string)`. */ + fun schema(string: String) = schema(Schema.ofString(string)) + + fun strict(strict: Boolean?) = strict(JsonField.ofNullable(strict)) + + /** + * Alias for [Builder.strict]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun strict(strict: Boolean) = strict(strict as Boolean?) + + /** Alias for calling [Builder.strict] with `strict.orElse(null)`. */ + fun strict(strict: Optional) = strict(strict.getOrNull()) + + /** + * Sets [Builder.strict] to an arbitrary JSON value. + * + * You should usually call [Builder.strict] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun strict(strict: JsonField) = apply { this.strict = strict } + + 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 [InnerJsonSchema]. + * + * 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(): InnerJsonSchema = + InnerJsonSchema( + checkRequired("name", name), + description, + schema, + strict, + additionalProperties.toImmutable(), + ) + } + + @JsonDeserialize(using = Schema.Deserializer::class) + @JsonSerialize(using = Schema.Serializer::class) + class Schema + private constructor( + private val object_: Object? = null, + private val string: String? = null, + private val _json: JsonValue? = null, + ) { + + fun object_(): Optional = Optional.ofNullable(object_) + + fun string(): Optional = Optional.ofNullable(string) + + fun isObject(): Boolean = object_ != null + + fun isString(): Boolean = string != null + + fun asObject(): Object = object_.getOrThrow("object_") + + fun asString(): String = string.getOrThrow("string") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + object_ != null -> visitor.visitObject(object_) + string != null -> visitor.visitString(string) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): Schema = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitObject(object_: Object) { + object_.validate() + } + + override fun visitString(string: String) {} + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Schema && object_ == other.object_ && string == other.string /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(object_, string) /* spotless:on */ + + override fun toString(): String = + when { + object_ != null -> "Schema{object_=$object_}" + string != null -> "Schema{string=$string}" + _json != null -> "Schema{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Schema") + } + + companion object { + + @JvmStatic fun ofObject(object_: Object) = Schema(object_ = object_) + + @JvmStatic fun ofString(string: String) = Schema(string = string) + } + + /** + * An interface that defines how to map each variant of [Schema] to a + * value of type [T]. + */ + interface Visitor { + + fun visitObject(object_: Object): T + + fun visitString(string: String): T + + /** + * Maps an unknown variant of [Schema] to a value of type [T]. + * + * An instance of [Schema] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For + * example, if the SDK is on an older version than the API, then the + * API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default + * implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Schema: $json") + } + } + + internal class Deserializer : BaseDeserializer(Schema::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Schema { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return Schema(object_ = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef())?.let { + return Schema(string = it, _json = json) + } + + return Schema(_json = json) + } + } + + internal class Serializer : BaseSerializer(Schema::class) { + + override fun serialize( + value: Schema, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.object_ != null -> + generator.writeObject(value.object_) + value.string != null -> generator.writeObject(value.string) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Schema") + } + } + } + + @NoAutoDetect + class Object + @JsonCreator + private constructor( + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap() + ) { + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + additionalProperties + + private var validated: Boolean = false + + fun validate(): Object = apply { + if (validated) { + return@apply + } + + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [Object]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Object]. */ + class Builder internal constructor() { + + private var additionalProperties: + MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(object_: Object) = apply { + additionalProperties = + object_.additionalProperties.toMutableMap() + } + + 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 [Object]. + * + * Further updates to this [Builder] will not mutate the + * returned instance. + */ + fun build(): Object = Object(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Object && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Object{additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InnerJsonSchema && name == other.name && description == other.description && schema == other.schema && strict == other.strict && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, description, schema, strict, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InnerJsonSchema{name=$name, description=$description, schema=$schema, strict=$strict, additionalProperties=$additionalProperties}" + } + + class Type + @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 JSON_SCHEMA = of("json_schema") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + JSON_SCHEMA + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { + JSON_SCHEMA, + /** + * An enum member indicating that [Type] 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) { + JSON_SCHEMA -> Value.JSON_SCHEMA + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + JSON_SCHEMA -> Known.JSON_SCHEMA + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is JsonSchema && jsonSchema == other.jsonSchema && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(jsonSchema, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "JsonSchema{jsonSchema=$jsonSchema, type=$type, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class Text + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Text = apply { + if (validated) { + return@apply + } + + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Text]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Text]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(text: Text) = apply { + type = text.type + additionalProperties = text.additionalProperties.toMutableMap() + } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [Text]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Text = + Text(checkRequired("type", type), additionalProperties.toImmutable()) + } + + class Type + @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 TEXT = of("text") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + TEXT + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { + TEXT, + /** + * An enum member indicating that [Type] 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) { + TEXT -> Value.TEXT + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + TEXT -> Known.TEXT + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Text && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Text{type=$type, additionalProperties=$additionalProperties}" + } + } + + @JsonDeserialize(using = ToolChoice.Deserializer::class) + @JsonSerialize(using = ToolChoice.Serializer::class) + class ToolChoice + private constructor( + private val unionMember0: UnionMember0? = null, + private val function: Function? = null, + private val _json: JsonValue? = null, + ) { + + fun unionMember0(): Optional = Optional.ofNullable(unionMember0) + + fun function(): Optional = Optional.ofNullable(function) + + fun isUnionMember0(): Boolean = unionMember0 != null + + fun isFunction(): Boolean = function != null + + fun asUnionMember0(): UnionMember0 = unionMember0.getOrThrow("unionMember0") + + fun asFunction(): Function = function.getOrThrow("function") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + unionMember0 != null -> visitor.visitUnionMember0(unionMember0) + function != null -> visitor.visitFunction(function) + else -> visitor.unknown(_json) + } + } + + private var validated: Boolean = false + + fun validate(): ToolChoice = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitUnionMember0(unionMember0: UnionMember0) {} + + override fun visitFunction(function: Function) { + function.validate() + } + } + ) + validated = true + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ToolChoice && unionMember0 == other.unionMember0 && function == other.function /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(unionMember0, function) /* spotless:on */ + + override fun toString(): String = + when { + unionMember0 != null -> "ToolChoice{unionMember0=$unionMember0}" + function != null -> "ToolChoice{function=$function}" + _json != null -> "ToolChoice{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ToolChoice") + } + + companion object { + + @JvmStatic + fun ofUnionMember0(unionMember0: UnionMember0) = + ToolChoice(unionMember0 = unionMember0) + + @JvmStatic fun ofFunction(function: Function) = ToolChoice(function = function) + } + + /** + * An interface that defines how to map each variant of [ToolChoice] to a value of + * type [T]. + */ + interface Visitor { + + fun visitUnionMember0(unionMember0: UnionMember0): T + + fun visitFunction(function: Function): T + + /** + * Maps an unknown variant of [ToolChoice] to a value of type [T]. + * + * An instance of [ToolChoice] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown ToolChoice: $json") + } + } + + internal class Deserializer : BaseDeserializer(ToolChoice::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ToolChoice { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef())?.let { + return ToolChoice(unionMember0 = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef()) { it.validate() } + ?.let { + return ToolChoice(function = it, _json = json) + } + + return ToolChoice(_json = json) + } + } + + internal class Serializer : BaseSerializer(ToolChoice::class) { + + override fun serialize( + value: ToolChoice, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.unionMember0 != null -> generator.writeObject(value.unionMember0) + value.function != null -> generator.writeObject(value.function) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ToolChoice") + } + } + } + + class UnionMember0 + @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 AUTO = of("auto") + + @JvmField val NONE = of("none") + + @JvmField val REQUIRED = of("required") + + @JvmStatic fun of(value: String) = UnionMember0(JsonField.of(value)) + } + + /** An enum containing [UnionMember0]'s known values. */ + enum class Known { + AUTO, + NONE, + REQUIRED, + } + + /** + * An enum containing [UnionMember0]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [UnionMember0] 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 { + AUTO, + NONE, + REQUIRED, + /** + * An enum member indicating that [UnionMember0] 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) { + AUTO -> Value.AUTO + NONE -> Value.NONE + REQUIRED -> Value.REQUIRED + 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 BraintrustInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + AUTO -> Known.AUTO + NONE -> Known.NONE + REQUIRED -> Known.REQUIRED + else -> + throw BraintrustInvalidDataException("Unknown UnionMember0: $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 BraintrustInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is UnionMember0 && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + @NoAutoDetect + class Function + @JsonCreator + private constructor( + @JsonProperty("function") + @ExcludeMissing + private val function: JsonField = JsonMissing.of(), + @JsonProperty("type") + @ExcludeMissing + private val type: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 function(): InnerFunction = function.getRequired("function") + + /** + * @throws BraintrustInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [function]. + * + * Unlike [function], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("function") + @ExcludeMissing + fun _function(): JsonField = function + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Function = apply { + if (validated) { + return@apply + } + + function().validate() + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Function]. + * + * The following fields are required: + * ```java + * .function() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Function]. */ + class Builder internal constructor() { + + private var function: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(function: Function) = apply { + this.function = function.function + type = function.type + additionalProperties = function.additionalProperties.toMutableMap() + } + + fun function(function: InnerFunction) = function(JsonField.of(function)) + + /** + * Sets [Builder.function] to an arbitrary JSON value. + * + * You should usually call [Builder.function] with a well-typed + * [InnerFunction] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun function(function: JsonField) = apply { + this.function = function + } + + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [Function]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .function() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Function = + Function( + checkRequired("function", function), + checkRequired("type", type), + additionalProperties.toImmutable(), + ) + } + + @NoAutoDetect + class InnerFunction + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = + immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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") + + /** + * 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 + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): InnerFunction = apply { + if (validated) { + return@apply + } + + name() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [InnerFunction]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InnerFunction]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(innerFunction: InnerFunction) = apply { + name = innerFunction.name + additionalProperties = + innerFunction.additionalProperties.toMutableMap() + } + + 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 } + + 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 [InnerFunction]. + * + * 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(): InnerFunction = + InnerFunction( + checkRequired("name", name), + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is InnerFunction && name == other.name && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InnerFunction{name=$name, additionalProperties=$additionalProperties}" + } + + class Type + @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 FUNCTION = of("function") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + FUNCTION + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Type] 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 { + FUNCTION, + /** + * An enum member indicating that [Type] 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) { + FUNCTION -> Value.FUNCTION + 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 BraintrustInvalidDataException if this class instance's value is + * a not a known member. + */ + fun known(): Known = + when (this) { + FUNCTION -> Known.FUNCTION + else -> throw BraintrustInvalidDataException("Unknown Type: $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 BraintrustInvalidDataException if this class instance's value + * does not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Type && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Function && function == other.function && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(function, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Function{function=$function, type=$type, additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is OpenAIModelParams && frequencyPenalty == other.frequencyPenalty && functionCall == other.functionCall && maxCompletionTokens == other.maxCompletionTokens && maxTokens == other.maxTokens && n == other.n && presencePenalty == other.presencePenalty && reasoningEffort == other.reasoningEffort && responseFormat == other.responseFormat && stop == other.stop && temperature == other.temperature && toolChoice == other.toolChoice && topP == other.topP && useCache == other.useCache && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(frequencyPenalty, functionCall, maxCompletionTokens, maxTokens, n, presencePenalty, reasoningEffort, responseFormat, stop, temperature, toolChoice, topP, useCache, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "OpenAIModelParams{frequencyPenalty=$frequencyPenalty, functionCall=$functionCall, maxCompletionTokens=$maxCompletionTokens, maxTokens=$maxTokens, n=$n, presencePenalty=$presencePenalty, reasoningEffort=$reasoningEffort, responseFormat=$responseFormat, stop=$stop, temperature=$temperature, toolChoice=$toolChoice, topP=$topP, useCache=$useCache, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class AnthropicModelParams + @JsonCreator + private constructor( + @JsonProperty("max_tokens") + @ExcludeMissing + private val maxTokens: JsonField = JsonMissing.of(), + @JsonProperty("temperature") + @ExcludeMissing + private val temperature: JsonField = JsonMissing.of(), + @JsonProperty("max_tokens_to_sample") + @ExcludeMissing + private val maxTokensToSample: JsonField = JsonMissing.of(), + @JsonProperty("stop_sequences") + @ExcludeMissing + private val stopSequences: JsonField> = JsonMissing.of(), + @JsonProperty("top_k") + @ExcludeMissing + private val topK: JsonField = JsonMissing.of(), + @JsonProperty("top_p") + @ExcludeMissing + private val topP: JsonField = JsonMissing.of(), + @JsonProperty("use_cache") + @ExcludeMissing + private val useCache: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException 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 maxTokens(): Double = maxTokens.getRequired("max_tokens") + + /** + * @throws BraintrustInvalidDataException 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 temperature(): Double = temperature.getRequired("temperature") + + /** + * This is a legacy parameter that should not be used. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun maxTokensToSample(): Optional = + Optional.ofNullable(maxTokensToSample.getNullable("max_tokens_to_sample")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun stopSequences(): Optional> = + Optional.ofNullable(stopSequences.getNullable("stop_sequences")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topK(): Optional = Optional.ofNullable(topK.getNullable("top_k")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topP(): Optional = Optional.ofNullable(topP.getNullable("top_p")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun useCache(): Optional = + Optional.ofNullable(useCache.getNullable("use_cache")) + + /** + * Returns the raw JSON value of [maxTokens]. + * + * Unlike [maxTokens], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("max_tokens") + @ExcludeMissing + fun _maxTokens(): JsonField = maxTokens + + /** + * Returns the raw JSON value of [temperature]. + * + * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("temperature") + @ExcludeMissing + fun _temperature(): JsonField = temperature + + /** + * Returns the raw JSON value of [maxTokensToSample]. + * + * Unlike [maxTokensToSample], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("max_tokens_to_sample") + @ExcludeMissing + fun _maxTokensToSample(): JsonField = maxTokensToSample + + /** + * Returns the raw JSON value of [stopSequences]. + * + * Unlike [stopSequences], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("stop_sequences") + @ExcludeMissing + fun _stopSequences(): JsonField> = stopSequences + + /** + * Returns the raw JSON value of [topK]. + * + * Unlike [topK], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("top_k") @ExcludeMissing fun _topK(): JsonField = topK + + /** + * Returns the raw JSON value of [topP]. + * + * Unlike [topP], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("top_p") @ExcludeMissing fun _topP(): JsonField = topP + + /** + * Returns the raw JSON value of [useCache]. + * + * Unlike [useCache], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("use_cache") + @ExcludeMissing + fun _useCache(): JsonField = useCache + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): AnthropicModelParams = apply { + if (validated) { + return@apply + } + + maxTokens() + temperature() + maxTokensToSample() + stopSequences() + topK() + topP() + useCache() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [AnthropicModelParams]. + * + * The following fields are required: + * ```java + * .maxTokens() + * .temperature() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AnthropicModelParams]. */ + class Builder internal constructor() { + + private var maxTokens: JsonField? = null + private var temperature: JsonField? = null + private var maxTokensToSample: JsonField = JsonMissing.of() + private var stopSequences: JsonField>? = null + private var topK: JsonField = JsonMissing.of() + private var topP: JsonField = JsonMissing.of() + private var useCache: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(anthropicModelParams: AnthropicModelParams) = apply { + maxTokens = anthropicModelParams.maxTokens + temperature = anthropicModelParams.temperature + maxTokensToSample = anthropicModelParams.maxTokensToSample + stopSequences = anthropicModelParams.stopSequences.map { it.toMutableList() } + topK = anthropicModelParams.topK + topP = anthropicModelParams.topP + useCache = anthropicModelParams.useCache + additionalProperties = anthropicModelParams.additionalProperties.toMutableMap() + } + + fun maxTokens(maxTokens: Double) = maxTokens(JsonField.of(maxTokens)) + + /** + * Sets [Builder.maxTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.maxTokens] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun maxTokens(maxTokens: JsonField) = apply { this.maxTokens = maxTokens } + + fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + + /** + * Sets [Builder.temperature] to an arbitrary JSON value. + * + * You should usually call [Builder.temperature] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun temperature(temperature: JsonField) = apply { + this.temperature = temperature + } + + /** This is a legacy parameter that should not be used. */ + fun maxTokensToSample(maxTokensToSample: Double) = + maxTokensToSample(JsonField.of(maxTokensToSample)) + + /** + * Sets [Builder.maxTokensToSample] to an arbitrary JSON value. + * + * You should usually call [Builder.maxTokensToSample] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun maxTokensToSample(maxTokensToSample: JsonField) = apply { + this.maxTokensToSample = maxTokensToSample + } + + fun stopSequences(stopSequences: List) = + stopSequences(JsonField.of(stopSequences)) + + /** + * Sets [Builder.stopSequences] to an arbitrary JSON value. + * + * You should usually call [Builder.stopSequences] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun stopSequences(stopSequences: JsonField>) = apply { + this.stopSequences = stopSequences.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [stopSequences]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addStopSequence(stopSequence: String) = apply { + stopSequences = + (stopSequences ?: JsonField.of(mutableListOf())).also { + checkKnown("stopSequences", it).add(stopSequence) + } + } + + fun topK(topK: Double) = topK(JsonField.of(topK)) + + /** + * Sets [Builder.topK] to an arbitrary JSON value. + * + * You should usually call [Builder.topK] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topK(topK: JsonField) = apply { this.topK = topK } + + fun topP(topP: Double) = topP(JsonField.of(topP)) + + /** + * Sets [Builder.topP] to an arbitrary JSON value. + * + * You should usually call [Builder.topP] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topP(topP: JsonField) = apply { this.topP = topP } + + fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + + /** + * Sets [Builder.useCache] to an arbitrary JSON value. + * + * You should usually call [Builder.useCache] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + + 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 [AnthropicModelParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .maxTokens() + * .temperature() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AnthropicModelParams = + AnthropicModelParams( + checkRequired("maxTokens", maxTokens), + checkRequired("temperature", temperature), + maxTokensToSample, + (stopSequences ?: JsonMissing.of()).map { it.toImmutable() }, + topK, + topP, + useCache, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is AnthropicModelParams && maxTokens == other.maxTokens && temperature == other.temperature && maxTokensToSample == other.maxTokensToSample && stopSequences == other.stopSequences && topK == other.topK && topP == other.topP && useCache == other.useCache && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(maxTokens, temperature, maxTokensToSample, stopSequences, topK, topP, useCache, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AnthropicModelParams{maxTokens=$maxTokens, temperature=$temperature, maxTokensToSample=$maxTokensToSample, stopSequences=$stopSequences, topK=$topK, topP=$topP, useCache=$useCache, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class GoogleModelParams + @JsonCreator + private constructor( + @JsonProperty("maxOutputTokens") + @ExcludeMissing + private val maxOutputTokens: JsonField = JsonMissing.of(), + @JsonProperty("temperature") + @ExcludeMissing + private val temperature: JsonField = JsonMissing.of(), + @JsonProperty("topK") + @ExcludeMissing + private val topK: JsonField = JsonMissing.of(), + @JsonProperty("topP") + @ExcludeMissing + private val topP: JsonField = JsonMissing.of(), + @JsonProperty("use_cache") + @ExcludeMissing + private val useCache: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun maxOutputTokens(): Optional = + Optional.ofNullable(maxOutputTokens.getNullable("maxOutputTokens")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun temperature(): Optional = + Optional.ofNullable(temperature.getNullable("temperature")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topK(): Optional = Optional.ofNullable(topK.getNullable("topK")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topP(): Optional = Optional.ofNullable(topP.getNullable("topP")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun useCache(): Optional = + Optional.ofNullable(useCache.getNullable("use_cache")) + + /** + * Returns the raw JSON value of [maxOutputTokens]. + * + * Unlike [maxOutputTokens], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("maxOutputTokens") + @ExcludeMissing + fun _maxOutputTokens(): JsonField = maxOutputTokens + + /** + * Returns the raw JSON value of [temperature]. + * + * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("temperature") + @ExcludeMissing + fun _temperature(): JsonField = temperature + + /** + * Returns the raw JSON value of [topK]. + * + * Unlike [topK], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topK") @ExcludeMissing fun _topK(): JsonField = topK + + /** + * Returns the raw JSON value of [topP]. + * + * Unlike [topP], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topP") @ExcludeMissing fun _topP(): JsonField = topP + + /** + * Returns the raw JSON value of [useCache]. + * + * Unlike [useCache], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("use_cache") + @ExcludeMissing + fun _useCache(): JsonField = useCache + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): GoogleModelParams = apply { + if (validated) { + return@apply + } + + maxOutputTokens() + temperature() + topK() + topP() + useCache() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [GoogleModelParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GoogleModelParams]. */ + class Builder internal constructor() { + + private var maxOutputTokens: JsonField = JsonMissing.of() + private var temperature: JsonField = JsonMissing.of() + private var topK: JsonField = JsonMissing.of() + private var topP: JsonField = JsonMissing.of() + private var useCache: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(googleModelParams: GoogleModelParams) = apply { + maxOutputTokens = googleModelParams.maxOutputTokens + temperature = googleModelParams.temperature + topK = googleModelParams.topK + topP = googleModelParams.topP + useCache = googleModelParams.useCache + additionalProperties = googleModelParams.additionalProperties.toMutableMap() + } + + fun maxOutputTokens(maxOutputTokens: Double) = + maxOutputTokens(JsonField.of(maxOutputTokens)) + + /** + * Sets [Builder.maxOutputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.maxOutputTokens] with a well-typed [Double] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun maxOutputTokens(maxOutputTokens: JsonField) = apply { + this.maxOutputTokens = maxOutputTokens + } + + fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + + /** + * Sets [Builder.temperature] to an arbitrary JSON value. + * + * You should usually call [Builder.temperature] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun temperature(temperature: JsonField) = apply { + this.temperature = temperature + } + + fun topK(topK: Double) = topK(JsonField.of(topK)) + + /** + * Sets [Builder.topK] to an arbitrary JSON value. + * + * You should usually call [Builder.topK] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topK(topK: JsonField) = apply { this.topK = topK } + + fun topP(topP: Double) = topP(JsonField.of(topP)) + + /** + * Sets [Builder.topP] to an arbitrary JSON value. + * + * You should usually call [Builder.topP] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topP(topP: JsonField) = apply { this.topP = topP } + + fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + + /** + * Sets [Builder.useCache] to an arbitrary JSON value. + * + * You should usually call [Builder.useCache] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + + 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 [GoogleModelParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): GoogleModelParams = + GoogleModelParams( + maxOutputTokens, + temperature, + topK, + topP, + useCache, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is GoogleModelParams && maxOutputTokens == other.maxOutputTokens && temperature == other.temperature && topK == other.topK && topP == other.topP && useCache == other.useCache && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(maxOutputTokens, temperature, topK, topP, useCache, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GoogleModelParams{maxOutputTokens=$maxOutputTokens, temperature=$temperature, topK=$topK, topP=$topP, useCache=$useCache, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class WindowAiModelParams + @JsonCreator + private constructor( + @JsonProperty("temperature") + @ExcludeMissing + private val temperature: JsonField = JsonMissing.of(), + @JsonProperty("topK") + @ExcludeMissing + private val topK: JsonField = JsonMissing.of(), + @JsonProperty("use_cache") + @ExcludeMissing + private val useCache: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun temperature(): Optional = + Optional.ofNullable(temperature.getNullable("temperature")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun topK(): Optional = Optional.ofNullable(topK.getNullable("topK")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun useCache(): Optional = + Optional.ofNullable(useCache.getNullable("use_cache")) + + /** + * Returns the raw JSON value of [temperature]. + * + * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("temperature") + @ExcludeMissing + fun _temperature(): JsonField = temperature + + /** + * Returns the raw JSON value of [topK]. + * + * Unlike [topK], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("topK") @ExcludeMissing fun _topK(): JsonField = topK + + /** + * Returns the raw JSON value of [useCache]. + * + * Unlike [useCache], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("use_cache") + @ExcludeMissing + fun _useCache(): JsonField = useCache + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): WindowAiModelParams = apply { + if (validated) { + return@apply + } + + temperature() + topK() + useCache() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [WindowAiModelParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [WindowAiModelParams]. */ + class Builder internal constructor() { + + private var temperature: JsonField = JsonMissing.of() + private var topK: JsonField = JsonMissing.of() + private var useCache: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(windowAiModelParams: WindowAiModelParams) = apply { + temperature = windowAiModelParams.temperature + topK = windowAiModelParams.topK + useCache = windowAiModelParams.useCache + additionalProperties = windowAiModelParams.additionalProperties.toMutableMap() + } + + fun temperature(temperature: Double) = temperature(JsonField.of(temperature)) + + /** + * Sets [Builder.temperature] to an arbitrary JSON value. + * + * You should usually call [Builder.temperature] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun temperature(temperature: JsonField) = apply { + this.temperature = temperature + } + + fun topK(topK: Double) = topK(JsonField.of(topK)) + + /** + * Sets [Builder.topK] to an arbitrary JSON value. + * + * You should usually call [Builder.topK] with a well-typed [Double] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topK(topK: JsonField) = apply { this.topK = topK } + + fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + + /** + * Sets [Builder.useCache] to an arbitrary JSON value. + * + * You should usually call [Builder.useCache] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + + 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 [WindowAiModelParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): WindowAiModelParams = + WindowAiModelParams( + temperature, + topK, + useCache, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is WindowAiModelParams && temperature == other.temperature && topK == other.topK && useCache == other.useCache && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(temperature, topK, useCache, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "WindowAiModelParams{temperature=$temperature, topK=$topK, useCache=$useCache, additionalProperties=$additionalProperties}" + } + + @NoAutoDetect + class JsCompletionParams + @JsonCreator + private constructor( + @JsonProperty("use_cache") + @ExcludeMissing + private val useCache: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun useCache(): Optional = + Optional.ofNullable(useCache.getNullable("use_cache")) + + /** + * Returns the raw JSON value of [useCache]. + * + * Unlike [useCache], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("use_cache") + @ExcludeMissing + fun _useCache(): JsonField = useCache + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): JsCompletionParams = apply { + if (validated) { + return@apply + } + + useCache() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [JsCompletionParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [JsCompletionParams]. */ + class Builder internal constructor() { + + private var useCache: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(jsCompletionParams: JsCompletionParams) = apply { + useCache = jsCompletionParams.useCache + additionalProperties = jsCompletionParams.additionalProperties.toMutableMap() + } + + fun useCache(useCache: Boolean) = useCache(JsonField.of(useCache)) + + /** + * Sets [Builder.useCache] to an arbitrary JSON value. + * + * You should usually call [Builder.useCache] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun useCache(useCache: JsonField) = apply { this.useCache = useCache } + + 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 [JsCompletionParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): JsCompletionParams = + JsCompletionParams(useCache, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is JsCompletionParams && useCache == other.useCache && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(useCache, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "JsCompletionParams{useCache=$useCache, additionalProperties=$additionalProperties}" + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptOptions && model == other.model && params == other.params && position == other.position && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(model, params, position, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PromptOptions{model=$model, params=$params, position=$position, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptReplaceParams.kt index ae734d51..7521b155 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptReplaceParams.kt @@ -5,430 +5,835 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace prompt. If there is an existing prompt in the project with the same slug as the + * one specified in the request, will replace the existing prompt with the provided fields + */ class PromptReplaceParams -constructor( - private val name: String, - private val projectId: String, - private val slug: String, - private val description: String?, - private val functionType: FunctionType?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun projectId(): String = projectId - - fun slug(): String = slug - - fun description(): Optional = Optional.ofNullable(description) - - fun functionType(): Optional = Optional.ofNullable(functionType) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): PromptReplaceBody { - return PromptReplaceBody( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = body.slug() + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun functionType(): Optional = body.functionType() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _slug(): JsonField = body._slug() + + /** + * 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 [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _functionType(): JsonField = body._functionType() + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = PromptReplaceBody.Builder::class) @NoAutoDetect - class PromptReplaceBody - internal constructor( - private val name: String?, - private val projectId: String?, - private val slug: String?, - private val description: String?, - private val functionType: FunctionType?, - private val promptData: PromptData?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("function_type") + @ExcludeMissing + private val functionType: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name - - /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") fun projectId(): String? = projectId - - /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(): String? = slug - - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description - - @JsonProperty("function_type") fun functionType(): FunctionType? = functionType - - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the prompt belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException 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 slug(): String = slug.getRequired("slug") + + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun functionType(): Optional = + Optional.ofNullable(functionType.getNullable("function_type")) + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * 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 [functionType]. + * + * Unlike [functionType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("function_type") + @ExcludeMissing + fun _functionType(): JsonField = functionType + + /** + * Returns the raw JSON value of [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is PromptReplaceBody && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionType == other.functionType && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalProperties, - ) - } - return hashCode + name() + projectId() + slug() + description() + functionType() + promptData().ifPresent { it.validate() } + tags() + validated = true } - override fun toString() = - "PromptReplaceBody{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalProperties=$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() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionType: FunctionType? = null - private var promptData: PromptData? = null - private var tags: List? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var slug: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var functionType: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(promptReplaceBody: PromptReplaceBody) = apply { - this.name = promptReplaceBody.name - this.projectId = promptReplaceBody.projectId - this.slug = promptReplaceBody.slug - this.description = promptReplaceBody.description - this.functionType = promptReplaceBody.functionType - this.promptData = promptReplaceBody.promptData - this.tags = promptReplaceBody.tags - additionalProperties(promptReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + slug = body.slug + description = body.description + functionType = body.functionType + promptData = body.promptData + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Unique identifier for the project that the prompt belongs under */ - @JsonProperty("project_id") - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = slug(JsonField.of(slug)) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } - @JsonProperty("function_type") - fun functionType(functionType: FunctionType) = apply { + fun functionType(functionType: FunctionType?) = + functionType(JsonField.ofNullable(functionType)) + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { this.functionType = functionType } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): PromptReplaceBody = - PromptReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, + 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() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("slug", slug), description, functionType, promptData, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && slug == other.slug && description == other.description && functionType == other.functionType && promptData == other.promptData && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is PromptReplaceParams && - this.name == other.name && - this.projectId == other.projectId && - this.slug == other.slug && - this.description == other.description && - this.functionType == other.functionType && - this.promptData == other.promptData && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, slug, description, functionType, promptData, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - projectId, - slug, - description, - functionType, - promptData, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "PromptReplaceParams{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, projectId=$projectId, slug=$slug, description=$description, functionType=$functionType, promptData=$promptData, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .slug() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptReplaceParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var projectId: String? = null - private var slug: String? = null - private var description: String? = null - private var functionType: FunctionType? = null - private var promptData: PromptData? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(promptReplaceParams: PromptReplaceParams) = apply { - this.name = promptReplaceParams.name - this.projectId = promptReplaceParams.projectId - this.slug = promptReplaceParams.slug - this.description = promptReplaceParams.description - this.functionType = promptReplaceParams.functionType - this.promptData = promptReplaceParams.promptData - this.tags(promptReplaceParams.tags ?: listOf()) - additionalQueryParams(promptReplaceParams.additionalQueryParams) - additionalHeaders(promptReplaceParams.additionalHeaders) - additionalBodyProperties(promptReplaceParams.additionalBodyProperties) + body = promptReplaceParams.body.toBuilder() + additionalHeaders = promptReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = promptReplaceParams.additionalQueryParams.toBuilder() } /** Name of the prompt */ - fun name(name: String) = apply { this.name = 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) } /** Unique identifier for the project that the prompt belongs under */ - fun projectId(projectId: String) = apply { this.projectId = projectId } + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } /** Unique identifier for the prompt */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String) = apply { body.slug(slug) } - /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun slug(slug: JsonField) = apply { body.slug(slug) } - fun functionType(functionType: FunctionType) = apply { this.functionType = functionType } + /** Textual description of the prompt */ + 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) } + + fun functionType(functionType: FunctionType?) = apply { body.functionType(functionType) } + + /** Alias for calling [Builder.functionType] with `functionType.orElse(null)`. */ + fun functionType(functionType: Optional) = + functionType(functionType.getOrNull()) + + /** + * Sets [Builder.functionType] to an arbitrary JSON value. + * + * You should usually call [Builder.functionType] with a well-typed [FunctionType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun functionType(functionType: JsonField) = apply { + body.functionType(functionType) + } /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) - } + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun tags(tags: List?) = apply { body.tags(tags) } + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + this.additionalQueryParams.putAll(additionalQueryParams) } - fun build(): PromptReplaceParams = - PromptReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(projectId) { "`projectId` is required but was not set" }, - checkNotNull(slug) { "`slug` is required but was not set" }, - description, - functionType, - promptData, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } - class FunctionType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - return other is FunctionType && this.value == other.value + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - override fun hashCode() = value.hashCode() + /** + * Returns an immutable instance of [PromptReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .slug() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PromptReplaceParams = + PromptReplaceParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - override fun toString() = value.toString() + class FunctionType @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 LLM = FunctionType(JsonField.of("llm")) + @JvmField val LLM = of("llm") - @JvmField val SCORER = FunctionType(JsonField.of("scorer")) + @JvmField val SCORER = of("scorer") - @JvmField val TASK = FunctionType(JsonField.of("task")) + @JvmField val TASK = of("task") - @JvmField val TOOL = FunctionType(JsonField.of("tool")) + @JvmField val TOOL = of("tool") @JvmStatic fun of(value: String) = FunctionType(JsonField.of(value)) } + /** An enum containing [FunctionType]'s known values. */ enum class Known { LLM, SCORER, @@ -436,14 +841,33 @@ constructor( TOOL, } + /** + * An enum containing [FunctionType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [FunctionType] 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 { LLM, SCORER, TASK, TOOL, + /** + * An enum member indicating that [FunctionType] 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) { LLM -> Value.LLM @@ -453,6 +877,15 @@ constructor( 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { LLM -> Known.LLM @@ -462,6 +895,43 @@ constructor( else -> throw BraintrustInvalidDataException("Unknown FunctionType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is FunctionType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "PromptReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptRetrieveParams.kt index 5fb7fad1..bd674855 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a prompt object by its id */ class PromptRetrieveParams -constructor( +private constructor( private val promptId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Prompt id */ fun promptId(): String = promptId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptRetrieveParams && - this.promptId == other.promptId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - promptId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "PromptRetrieveParams{promptId=$promptId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptRetrieveParams]. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var promptId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(promptRetrieveParams: PromptRetrieveParams) = apply { - this.promptId = promptRetrieveParams.promptId - additionalQueryParams(promptRetrieveParams.additionalQueryParams) - additionalHeaders(promptRetrieveParams.additionalHeaders) + promptId = promptRetrieveParams.promptId + additionalHeaders = promptRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = promptRetrieveParams.additionalQueryParams.toBuilder() } /** Prompt id */ fun promptId(promptId: String) = apply { this.promptId = promptId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [PromptRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): PromptRetrieveParams = PromptRetrieveParams( - checkNotNull(promptId) { "`promptId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("promptId", promptId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptRetrieveParams && promptId == other.promptId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(promptId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "PromptRetrieveParams{promptId=$promptId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptUpdateParams.kt index 334bbcba..2e6f019a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/PromptUpdateParams.kt @@ -3,57 +3,128 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a prompt object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class PromptUpdateParams -constructor( +private constructor( private val promptId: String, - private val description: String?, - private val name: String?, - private val promptData: PromptData?, - private val slug: String?, - private val tags: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Prompt id */ fun promptId(): String = promptId - fun description(): Optional = Optional.ofNullable(description) - - fun name(): Optional = Optional.ofNullable(name) - - fun promptData(): Optional = Optional.ofNullable(promptData) - - fun slug(): Optional = Optional.ofNullable(slug) - - fun tags(): Optional> = Optional.ofNullable(tags) - - @JvmSynthetic - internal fun getBody(): PromptUpdateBody { - return PromptUpdateBody( - description, - name, - promptData, - slug, - tags, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun promptData(): Optional = body.promptData() + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun slug(): Optional = body.slug() + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException 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 [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 [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 [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _promptData(): JsonField = body._promptData() + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _slug(): JsonField = body._slug() + + /** + * 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() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -62,302 +133,564 @@ constructor( } } - @JsonDeserialize(builder = PromptUpdateBody.Builder::class) @NoAutoDetect - class PromptUpdateBody - internal constructor( - private val description: String?, - private val name: String?, - private val promptData: PromptData?, - private val slug: String?, - private val tags: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("prompt_data") + @ExcludeMissing + private val promptData: JsonField = JsonMissing.of(), + @JsonProperty("slug") + @ExcludeMissing + private val slug: JsonField = JsonMissing.of(), + @JsonProperty("tags") + @ExcludeMissing + private val tags: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Textual description of the prompt */ - @JsonProperty("description") fun description(): String? = description - - /** Name of the prompt */ - @JsonProperty("name") fun name(): String? = name - - /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") fun promptData(): PromptData? = promptData - - /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(): String? = slug - - /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(): List? = tags + /** + * Textual description of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * The prompt, model, and its parameters + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun promptData(): Optional = + Optional.ofNullable(promptData.getNullable("prompt_data")) + + /** + * Unique identifier for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun slug(): Optional = Optional.ofNullable(slug.getNullable("slug")) + + /** + * A list of tags for the prompt + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun tags(): Optional> = Optional.ofNullable(tags.getNullable("tags")) + + /** + * 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 [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 [promptData]. + * + * Unlike [promptData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("prompt_data") + @ExcludeMissing + fun _promptData(): JsonField = promptData + + /** + * Returns the raw JSON value of [slug]. + * + * Unlike [slug], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("slug") @ExcludeMissing fun _slug(): JsonField = slug + + /** + * 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 @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is PromptUpdateBody && - this.description == other.description && - this.name == other.name && - this.promptData == other.promptData && - this.slug == other.slug && - this.tags == other.tags && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - description, - name, - promptData, - slug, - tags, - additionalProperties, - ) - } - return hashCode + description() + name() + promptData().ifPresent { it.validate() } + slug() + tags() + validated = true } - override fun toString() = - "PromptUpdateBody{description=$description, name=$name, promptData=$promptData, slug=$slug, tags=$tags, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var description: String? = null - private var name: String? = null - private var promptData: PromptData? = null - private var slug: String? = null - private var tags: List? = null + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var promptData: JsonField = JsonMissing.of() + private var slug: JsonField = JsonMissing.of() + private var tags: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(promptUpdateBody: PromptUpdateBody) = apply { - this.description = promptUpdateBody.description - this.name = promptUpdateBody.name - this.promptData = promptUpdateBody.promptData - this.slug = promptUpdateBody.slug - this.tags = promptUpdateBody.tags - additionalProperties(promptUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + description = body.description + name = body.name + promptData = body.promptData + slug = body.slug + tags = body.tags.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** Textual description of the prompt */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** Name of the prompt */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** The prompt, model, and its parameters */ - @JsonProperty("prompt_data") - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = promptData(JsonField.ofNullable(promptData)) + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { + this.promptData = promptData + } /** Unique identifier for the prompt */ - @JsonProperty("slug") fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String?) = slug(JsonField.ofNullable(slug)) + + /** Alias for calling [Builder.slug] with `slug.orElse(null)`. */ + fun slug(slug: Optional) = slug(slug.getOrNull()) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun slug(slug: JsonField) = apply { this.slug = slug } /** A list of tags for the prompt */ - @JsonProperty("tags") fun tags(tags: List) = apply { this.tags = tags } + fun tags(tags: List?) = tags(JsonField.ofNullable(tags)) + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): PromptUpdateBody = - PromptUpdateBody( + 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. + */ + fun build(): Body = + Body( description, name, promptData, slug, - tags?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (tags ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && description == other.description && name == other.name && promptData == other.promptData && slug == other.slug && tags == other.tags && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is PromptUpdateParams && - this.promptId == other.promptId && - this.description == other.description && - this.name == other.name && - this.promptData == other.promptData && - this.slug == other.slug && - this.tags == other.tags && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(description, name, promptData, slug, tags, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - promptId, - description, - name, - promptData, - slug, - tags, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "PromptUpdateParams{promptId=$promptId, description=$description, name=$name, promptData=$promptData, slug=$slug, tags=$tags, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{description=$description, name=$name, promptData=$promptData, slug=$slug, tags=$tags, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [PromptUpdateParams]. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [PromptUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var promptId: String? = null - private var description: String? = null - private var name: String? = null - private var promptData: PromptData? = null - private var slug: String? = null - private var tags: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(promptUpdateParams: PromptUpdateParams) = apply { - this.promptId = promptUpdateParams.promptId - this.description = promptUpdateParams.description - this.name = promptUpdateParams.name - this.promptData = promptUpdateParams.promptData - this.slug = promptUpdateParams.slug - this.tags(promptUpdateParams.tags ?: listOf()) - additionalQueryParams(promptUpdateParams.additionalQueryParams) - additionalHeaders(promptUpdateParams.additionalHeaders) - additionalBodyProperties(promptUpdateParams.additionalBodyProperties) + promptId = promptUpdateParams.promptId + body = promptUpdateParams.body.toBuilder() + additionalHeaders = promptUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = promptUpdateParams.additionalQueryParams.toBuilder() } /** Prompt id */ fun promptId(promptId: String) = apply { this.promptId = promptId } /** Textual description of the prompt */ - fun description(description: String) = apply { this.description = description } + 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) } /** Name of the prompt */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } /** The prompt, model, and its parameters */ - fun promptData(promptData: PromptData) = apply { this.promptData = promptData } + fun promptData(promptData: PromptData?) = apply { body.promptData(promptData) } + + /** Alias for calling [Builder.promptData] with `promptData.orElse(null)`. */ + fun promptData(promptData: Optional) = promptData(promptData.getOrNull()) + + /** + * Sets [Builder.promptData] to an arbitrary JSON value. + * + * You should usually call [Builder.promptData] with a well-typed [PromptData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptData(promptData: JsonField) = apply { body.promptData(promptData) } /** Unique identifier for the prompt */ - fun slug(slug: String) = apply { this.slug = slug } + fun slug(slug: String?) = apply { body.slug(slug) } - /** A list of tags for the prompt */ - fun tags(tags: List) = apply { - this.tags.clear() - this.tags.addAll(tags) - } + /** Alias for calling [Builder.slug] with `slug.orElse(null)`. */ + fun slug(slug: Optional) = slug(slug.getOrNull()) + + /** + * Sets [Builder.slug] to an arbitrary JSON value. + * + * You should usually call [Builder.slug] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun slug(slug: JsonField) = apply { body.slug(slug) } /** A list of tags for the prompt */ - fun addTag(tag: String) = apply { this.tags.add(tag) } + fun tags(tags: List?) = apply { body.tags(tags) } + + /** Alias for calling [Builder.tags] with `tags.orElse(null)`. */ + fun tags(tags: Optional>) = tags(tags.getOrNull()) + + /** + * 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 additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [PromptUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .promptId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): PromptUpdateParams = PromptUpdateParams( - checkNotNull(promptId) { "`promptId` is required but was not set" }, - description, - name, - promptData, - slug, - if (tags.size == 0) null else tags.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("promptId", promptId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is PromptUpdateParams && promptId == other.promptId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(promptId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "PromptUpdateParams{promptId=$promptId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RepoInfo.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RepoInfo.kt index 6447c8f7..0ce351bc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RepoInfo.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RepoInfo.kt @@ -7,296 +7,446 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Metadata about the state of the repo when the experiment was created */ -@JsonDeserialize(builder = RepoInfo.Builder::class) @NoAutoDetect class RepoInfo +@JsonCreator private constructor( - private val commit: JsonField, - private val branch: JsonField, - private val tag: JsonField, - private val dirty: JsonField, - private val authorName: JsonField, - private val authorEmail: JsonField, - private val commitMessage: JsonField, - private val commitTime: JsonField, - private val gitDiff: JsonField, - private val additionalProperties: Map, + @JsonProperty("author_email") + @ExcludeMissing + private val authorEmail: JsonField = JsonMissing.of(), + @JsonProperty("author_name") + @ExcludeMissing + private val authorName: JsonField = JsonMissing.of(), + @JsonProperty("branch") + @ExcludeMissing + private val branch: JsonField = JsonMissing.of(), + @JsonProperty("commit") + @ExcludeMissing + private val commit: JsonField = JsonMissing.of(), + @JsonProperty("commit_message") + @ExcludeMissing + private val commitMessage: JsonField = JsonMissing.of(), + @JsonProperty("commit_time") + @ExcludeMissing + private val commitTime: JsonField = JsonMissing.of(), + @JsonProperty("dirty") @ExcludeMissing private val dirty: JsonField = JsonMissing.of(), + @JsonProperty("git_diff") + @ExcludeMissing + private val gitDiff: JsonField = JsonMissing.of(), + @JsonProperty("tag") @ExcludeMissing private val tag: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * Email of the author of the most recent commit + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun authorEmail(): Optional = + Optional.ofNullable(authorEmail.getNullable("author_email")) - /** SHA of most recent commit */ - fun commit(): Optional = Optional.ofNullable(commit.getNullable("commit")) + /** + * Name of the author of the most recent commit + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun authorName(): Optional = Optional.ofNullable(authorName.getNullable("author_name")) - /** Name of the branch the most recent commit belongs to */ + /** + * Name of the branch the most recent commit belongs to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun branch(): Optional = Optional.ofNullable(branch.getNullable("branch")) - /** Name of the tag on the most recent commit */ - fun tag(): Optional = Optional.ofNullable(tag.getNullable("tag")) - - /** Whether or not the repo had uncommitted changes when snapshotted */ - fun dirty(): Optional = Optional.ofNullable(dirty.getNullable("dirty")) - - /** Name of the author of the most recent commit */ - fun authorName(): Optional = Optional.ofNullable(authorName.getNullable("author_name")) - - /** Email of the author of the most recent commit */ - fun authorEmail(): Optional = - Optional.ofNullable(authorEmail.getNullable("author_email")) + /** + * SHA of most recent commit + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun commit(): Optional = Optional.ofNullable(commit.getNullable("commit")) - /** Most recent commit message */ + /** + * Most recent commit message + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun commitMessage(): Optional = Optional.ofNullable(commitMessage.getNullable("commit_message")) - /** Time of the most recent commit */ + /** + * Time of the most recent commit + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun commitTime(): Optional = Optional.ofNullable(commitTime.getNullable("commit_time")) + /** + * Whether or not the repo had uncommitted changes when snapshotted + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun dirty(): Optional = Optional.ofNullable(dirty.getNullable("dirty")) + /** * If the repo was dirty when run, this includes the diff between the current state of the repo * and the most recent commit. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun gitDiff(): Optional = Optional.ofNullable(gitDiff.getNullable("git_diff")) - /** SHA of most recent commit */ - @JsonProperty("commit") @ExcludeMissing fun _commit() = commit + /** + * Name of the tag on the most recent commit + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tag(): Optional = Optional.ofNullable(tag.getNullable("tag")) + + /** + * Returns the raw JSON value of [authorEmail]. + * + * Unlike [authorEmail], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("author_email") + @ExcludeMissing + fun _authorEmail(): JsonField = authorEmail - /** Name of the branch the most recent commit belongs to */ - @JsonProperty("branch") @ExcludeMissing fun _branch() = branch + /** + * Returns the raw JSON value of [authorName]. + * + * Unlike [authorName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("author_name") @ExcludeMissing fun _authorName(): JsonField = authorName - /** Name of the tag on the most recent commit */ - @JsonProperty("tag") @ExcludeMissing fun _tag() = tag + /** + * Returns the raw JSON value of [branch]. + * + * Unlike [branch], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("branch") @ExcludeMissing fun _branch(): JsonField = branch - /** Whether or not the repo had uncommitted changes when snapshotted */ - @JsonProperty("dirty") @ExcludeMissing fun _dirty() = dirty + /** + * Returns the raw JSON value of [commit]. + * + * Unlike [commit], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("commit") @ExcludeMissing fun _commit(): JsonField = commit - /** Name of the author of the most recent commit */ - @JsonProperty("author_name") @ExcludeMissing fun _authorName() = authorName + /** + * Returns the raw JSON value of [commitMessage]. + * + * Unlike [commitMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("commit_message") + @ExcludeMissing + fun _commitMessage(): JsonField = commitMessage - /** Email of the author of the most recent commit */ - @JsonProperty("author_email") @ExcludeMissing fun _authorEmail() = authorEmail + /** + * Returns the raw JSON value of [commitTime]. + * + * Unlike [commitTime], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("commit_time") @ExcludeMissing fun _commitTime(): JsonField = commitTime - /** Most recent commit message */ - @JsonProperty("commit_message") @ExcludeMissing fun _commitMessage() = commitMessage + /** + * Returns the raw JSON value of [dirty]. + * + * Unlike [dirty], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dirty") @ExcludeMissing fun _dirty(): JsonField = dirty - /** Time of the most recent commit */ - @JsonProperty("commit_time") @ExcludeMissing fun _commitTime() = commitTime + /** + * Returns the raw JSON value of [gitDiff]. + * + * Unlike [gitDiff], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("git_diff") @ExcludeMissing fun _gitDiff(): JsonField = gitDiff /** - * If the repo was dirty when run, this includes the diff between the current state of the repo - * and the most recent commit. + * Returns the raw JSON value of [tag]. + * + * Unlike [tag], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("git_diff") @ExcludeMissing fun _gitDiff() = gitDiff + @JsonProperty("tag") @ExcludeMissing fun _tag(): JsonField = tag @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): RepoInfo = apply { - if (!validated) { - commit() - branch() - tag() - dirty() - authorName() - authorEmail() - commitMessage() - commitTime() - gitDiff() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RepoInfo = apply { + if (validated) { + return@apply } - return other is RepoInfo && - this.commit == other.commit && - this.branch == other.branch && - this.tag == other.tag && - this.dirty == other.dirty && - this.authorName == other.authorName && - this.authorEmail == other.authorEmail && - this.commitMessage == other.commitMessage && - this.commitTime == other.commitTime && - this.gitDiff == other.gitDiff && - this.additionalProperties == other.additionalProperties + authorEmail() + authorName() + branch() + commit() + commitMessage() + commitTime() + dirty() + gitDiff() + tag() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - commit, - branch, - tag, - dirty, - authorName, - authorEmail, - commitMessage, - commitTime, - gitDiff, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "RepoInfo{commit=$commit, branch=$branch, tag=$tag, dirty=$dirty, authorName=$authorName, authorEmail=$authorEmail, commitMessage=$commitMessage, commitTime=$commitTime, gitDiff=$gitDiff, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [RepoInfo]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RepoInfo]. */ + class Builder internal constructor() { - private var commit: JsonField = JsonMissing.of() - private var branch: JsonField = JsonMissing.of() - private var tag: JsonField = JsonMissing.of() - private var dirty: JsonField = JsonMissing.of() - private var authorName: JsonField = JsonMissing.of() private var authorEmail: JsonField = JsonMissing.of() + private var authorName: JsonField = JsonMissing.of() + private var branch: JsonField = JsonMissing.of() + private var commit: JsonField = JsonMissing.of() private var commitMessage: JsonField = JsonMissing.of() private var commitTime: JsonField = JsonMissing.of() + private var dirty: JsonField = JsonMissing.of() private var gitDiff: JsonField = JsonMissing.of() + private var tag: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(repoInfo: RepoInfo) = apply { - this.commit = repoInfo.commit - this.branch = repoInfo.branch - this.tag = repoInfo.tag - this.dirty = repoInfo.dirty - this.authorName = repoInfo.authorName - this.authorEmail = repoInfo.authorEmail - this.commitMessage = repoInfo.commitMessage - this.commitTime = repoInfo.commitTime - this.gitDiff = repoInfo.gitDiff - additionalProperties(repoInfo.additionalProperties) + authorEmail = repoInfo.authorEmail + authorName = repoInfo.authorName + branch = repoInfo.branch + commit = repoInfo.commit + commitMessage = repoInfo.commitMessage + commitTime = repoInfo.commitTime + dirty = repoInfo.dirty + gitDiff = repoInfo.gitDiff + tag = repoInfo.tag + additionalProperties = repoInfo.additionalProperties.toMutableMap() } - /** SHA of most recent commit */ - fun commit(commit: String) = commit(JsonField.of(commit)) + /** Email of the author of the most recent commit */ + fun authorEmail(authorEmail: String?) = authorEmail(JsonField.ofNullable(authorEmail)) - /** SHA of most recent commit */ - @JsonProperty("commit") - @ExcludeMissing - fun commit(commit: JsonField) = apply { this.commit = commit } + /** Alias for calling [Builder.authorEmail] with `authorEmail.orElse(null)`. */ + fun authorEmail(authorEmail: Optional) = authorEmail(authorEmail.getOrNull()) - /** Name of the branch the most recent commit belongs to */ - fun branch(branch: String) = branch(JsonField.of(branch)) + /** + * Sets [Builder.authorEmail] to an arbitrary JSON value. + * + * You should usually call [Builder.authorEmail] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun authorEmail(authorEmail: JsonField) = apply { this.authorEmail = authorEmail } - /** Name of the branch the most recent commit belongs to */ - @JsonProperty("branch") - @ExcludeMissing - fun branch(branch: JsonField) = apply { this.branch = branch } + /** Name of the author of the most recent commit */ + fun authorName(authorName: String?) = authorName(JsonField.ofNullable(authorName)) - /** Name of the tag on the most recent commit */ - fun tag(tag: String) = tag(JsonField.of(tag)) + /** Alias for calling [Builder.authorName] with `authorName.orElse(null)`. */ + fun authorName(authorName: Optional) = authorName(authorName.getOrNull()) - /** Name of the tag on the most recent commit */ - @JsonProperty("tag") - @ExcludeMissing - fun tag(tag: JsonField) = apply { this.tag = tag } + /** + * Sets [Builder.authorName] to an arbitrary JSON value. + * + * You should usually call [Builder.authorName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun authorName(authorName: JsonField) = apply { this.authorName = authorName } - /** Whether or not the repo had uncommitted changes when snapshotted */ - fun dirty(dirty: Boolean) = dirty(JsonField.of(dirty)) + /** Name of the branch the most recent commit belongs to */ + fun branch(branch: String?) = branch(JsonField.ofNullable(branch)) - /** Whether or not the repo had uncommitted changes when snapshotted */ - @JsonProperty("dirty") - @ExcludeMissing - fun dirty(dirty: JsonField) = apply { this.dirty = dirty } + /** Alias for calling [Builder.branch] with `branch.orElse(null)`. */ + fun branch(branch: Optional) = branch(branch.getOrNull()) - /** Name of the author of the most recent commit */ - fun authorName(authorName: String) = authorName(JsonField.of(authorName)) + /** + * Sets [Builder.branch] to an arbitrary JSON value. + * + * You should usually call [Builder.branch] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun branch(branch: JsonField) = apply { this.branch = branch } - /** Name of the author of the most recent commit */ - @JsonProperty("author_name") - @ExcludeMissing - fun authorName(authorName: JsonField) = apply { this.authorName = authorName } + /** SHA of most recent commit */ + fun commit(commit: String?) = commit(JsonField.ofNullable(commit)) - /** Email of the author of the most recent commit */ - fun authorEmail(authorEmail: String) = authorEmail(JsonField.of(authorEmail)) + /** Alias for calling [Builder.commit] with `commit.orElse(null)`. */ + fun commit(commit: Optional) = commit(commit.getOrNull()) - /** Email of the author of the most recent commit */ - @JsonProperty("author_email") - @ExcludeMissing - fun authorEmail(authorEmail: JsonField) = apply { this.authorEmail = authorEmail } + /** + * Sets [Builder.commit] to an arbitrary JSON value. + * + * You should usually call [Builder.commit] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun commit(commit: JsonField) = apply { this.commit = commit } /** Most recent commit message */ - fun commitMessage(commitMessage: String) = commitMessage(JsonField.of(commitMessage)) + fun commitMessage(commitMessage: String?) = + commitMessage(JsonField.ofNullable(commitMessage)) - /** Most recent commit message */ - @JsonProperty("commit_message") - @ExcludeMissing + /** Alias for calling [Builder.commitMessage] with `commitMessage.orElse(null)`. */ + fun commitMessage(commitMessage: Optional) = + commitMessage(commitMessage.getOrNull()) + + /** + * Sets [Builder.commitMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.commitMessage] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun commitMessage(commitMessage: JsonField) = apply { this.commitMessage = commitMessage } /** Time of the most recent commit */ - fun commitTime(commitTime: String) = commitTime(JsonField.of(commitTime)) + fun commitTime(commitTime: String?) = commitTime(JsonField.ofNullable(commitTime)) - /** Time of the most recent commit */ - @JsonProperty("commit_time") - @ExcludeMissing + /** Alias for calling [Builder.commitTime] with `commitTime.orElse(null)`. */ + fun commitTime(commitTime: Optional) = commitTime(commitTime.getOrNull()) + + /** + * Sets [Builder.commitTime] to an arbitrary JSON value. + * + * You should usually call [Builder.commitTime] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun commitTime(commitTime: JsonField) = apply { this.commitTime = commitTime } + /** Whether or not the repo had uncommitted changes when snapshotted */ + fun dirty(dirty: Boolean?) = dirty(JsonField.ofNullable(dirty)) + /** - * If the repo was dirty when run, this includes the diff between the current state of the - * repo and the most recent commit. + * Alias for [Builder.dirty]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun dirty(dirty: Boolean) = dirty(dirty as Boolean?) + + /** Alias for calling [Builder.dirty] with `dirty.orElse(null)`. */ + fun dirty(dirty: Optional) = dirty(dirty.getOrNull()) + + /** + * Sets [Builder.dirty] to an arbitrary JSON value. + * + * You should usually call [Builder.dirty] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. */ - fun gitDiff(gitDiff: String) = gitDiff(JsonField.of(gitDiff)) + fun dirty(dirty: JsonField) = apply { this.dirty = dirty } /** * If the repo was dirty when run, this includes the diff between the current state of the * repo and the most recent commit. */ - @JsonProperty("git_diff") - @ExcludeMissing + fun gitDiff(gitDiff: String?) = gitDiff(JsonField.ofNullable(gitDiff)) + + /** Alias for calling [Builder.gitDiff] with `gitDiff.orElse(null)`. */ + fun gitDiff(gitDiff: Optional) = gitDiff(gitDiff.getOrNull()) + + /** + * Sets [Builder.gitDiff] to an arbitrary JSON value. + * + * You should usually call [Builder.gitDiff] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun gitDiff(gitDiff: JsonField) = apply { this.gitDiff = gitDiff } + /** Name of the tag on the most recent commit */ + fun tag(tag: String?) = tag(JsonField.ofNullable(tag)) + + /** Alias for calling [Builder.tag] with `tag.orElse(null)`. */ + fun tag(tag: Optional) = tag(tag.getOrNull()) + + /** + * Sets [Builder.tag] to an arbitrary JSON value. + * + * You should usually call [Builder.tag] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun tag(tag: JsonField) = apply { this.tag = tag } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RepoInfo]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): RepoInfo = RepoInfo( - commit, - branch, - tag, - dirty, - authorName, authorEmail, + authorName, + branch, + commit, commitMessage, commitTime, + dirty, gitDiff, - additionalProperties.toUnmodifiable(), + tag, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RepoInfo && authorEmail == other.authorEmail && authorName == other.authorName && branch == other.branch && commit == other.commit && commitMessage == other.commitMessage && commitTime == other.commitTime && dirty == other.dirty && gitDiff == other.gitDiff && tag == other.tag && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(authorEmail, authorName, branch, commit, commitMessage, commitTime, dirty, gitDiff, tag, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RepoInfo{authorEmail=$authorEmail, authorName=$authorName, branch=$branch, commit=$commit, commitMessage=$commitMessage, commitTime=$commitTime, dirty=$dirty, gitDiff=$gitDiff, tag=$tag, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Role.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Role.kt index a5d749f1..43105f4e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Role.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Role.kt @@ -2,79 +2,106 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** * A role is a collection of permissions which can be granted as part of an ACL * * Roles can consist of individual permissions, as well as a set of roles they inherit from */ -@JsonDeserialize(builder = Role.Builder::class) @NoAutoDetect class Role +@JsonCreator private constructor( - private val id: JsonField, - private val orgId: JsonField, - private val userId: JsonField, - private val created: JsonField, - private val name: JsonField, - private val description: JsonField, - private val deletedAt: JsonField, - private val memberPermissions: JsonField>, - private val memberRoles: JsonField>, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_permissions") + @ExcludeMissing + private val memberPermissions: JsonField> = JsonMissing.of(), + @JsonProperty("member_roles") + @ExcludeMissing + private val memberRoles: JsonField> = JsonMissing.of(), + @JsonProperty("org_id") @ExcludeMissing private val orgId: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the role */ + /** + * Unique identifier for the role + * + * @throws BraintrustInvalidDataException 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") /** - * Unique id for the organization that the role belongs under - * - * A null org_id indicates a system role, which may be assigned to anybody and inherited by any - * other role, but cannot be edited. + * Name of the role * - * It is forbidden to change the org after creating a role + * @throws BraintrustInvalidDataException 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 orgId(): Optional = Optional.ofNullable(orgId.getNullable("org_id")) - - /** Identifies the user who created the role */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + fun name(): String = name.getRequired("name") - /** Date of role creation */ + /** + * Date of role creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Name of the role */ - fun name(): String = name.getRequired("name") + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun deletedAt(): Optional = + Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Textual description of the role */ + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun description(): Optional = Optional.ofNullable(description.getNullable("description")) - /** Date of role deletion, or null if the role is still active */ - fun deletedAt(): Optional = - Optional.ofNullable(deletedAt.getNullable("deleted_at")) - - /** (permission, restrict_object_type) tuples which belong to this role */ + /** + * (permission, restrict_object_type) tuples which belong to this role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun memberPermissions(): Optional> = Optional.ofNullable(memberPermissions.getNullable("member_permissions")) @@ -83,13 +110,13 @@ private constructor( * * An inheriting role has all the permissions contained in its member roles, as well as all of * their inherited permissions + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ fun memberRoles(): Optional> = Optional.ofNullable(memberRoles.getNullable("member_roles")) - /** Unique identifier for the role */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - /** * Unique id for the organization that the role belongs under * @@ -97,214 +124,254 @@ private constructor( * other role, but cannot be edited. * * It is forbidden to change the org after creating a role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - @JsonProperty("org_id") @ExcludeMissing fun _orgId() = orgId + fun orgId(): Optional = Optional.ofNullable(orgId.getNullable("org_id")) - /** Identifies the user who created the role */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * Identifies the user who created the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Date of role creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 - /** Name of the role */ - @JsonProperty("name") @ExcludeMissing fun _name() = name + /** + * 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 - /** Textual description of the role */ - @JsonProperty("description") @ExcludeMissing fun _description() = description + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt - /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") @ExcludeMissing fun _memberPermissions() = memberPermissions + /** + * 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 /** - * Ids of the roles this role inherits from + * Returns the raw JSON value of [memberPermissions]. * - * An inheriting role has all the permissions contained in its member roles, as well as all of - * their inherited permissions + * Unlike [memberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. */ - @JsonProperty("member_roles") @ExcludeMissing fun _memberRoles() = memberRoles + @JsonProperty("member_permissions") + @ExcludeMissing + fun _memberPermissions(): JsonField> = memberPermissions - @JsonAnyGetter + /** + * Returns the raw JSON value of [memberRoles]. + * + * Unlike [memberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_roles") @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + fun _memberRoles(): JsonField> = memberRoles - fun validate(): Role = apply { - if (!validated) { - id() - orgId() - userId() - created() - name() - description() - deletedAt() - memberPermissions().map { it.forEach { it.validate() } } - memberRoles() - validated = true - } - } + /** + * Returns the raw JSON value of [orgId]. + * + * Unlike [orgId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_id") @ExcludeMissing fun _orgId(): JsonField = orgId - fun toBuilder() = Builder().from(this) + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - return other is Role && - this.id == other.id && - this.orgId == other.orgId && - this.userId == other.userId && - this.created == other.created && - this.name == other.name && - this.description == other.description && - this.deletedAt == other.deletedAt && - this.memberPermissions == other.memberPermissions && - this.memberRoles == other.memberRoles && - this.additionalProperties == other.additionalProperties - } + private var validated: Boolean = false - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - orgId, - userId, - created, - name, - description, - deletedAt, - memberPermissions, - memberRoles, - additionalProperties, - ) + fun validate(): Role = apply { + if (validated) { + return@apply } - return hashCode + + id() + name() + created() + deletedAt() + description() + memberPermissions().ifPresent { it.forEach { it.validate() } } + memberRoles() + orgId() + userId() + validated = true } - override fun toString() = - "Role{id=$id, orgId=$orgId, userId=$userId, created=$created, name=$name, description=$description, deletedAt=$deletedAt, memberPermissions=$memberPermissions, memberRoles=$memberRoles, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Role]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Role]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var orgId: JsonField = JsonMissing.of() - private var userId: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null private var created: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() - private var description: JsonField = JsonMissing.of() private var deletedAt: JsonField = JsonMissing.of() - private var memberPermissions: JsonField> = JsonMissing.of() - private var memberRoles: JsonField> = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var memberPermissions: JsonField>? = null + private var memberRoles: JsonField>? = null + private var orgId: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(role: Role) = apply { - this.id = role.id - this.orgId = role.orgId - this.userId = role.userId - this.created = role.created - this.name = role.name - this.description = role.description - this.deletedAt = role.deletedAt - this.memberPermissions = role.memberPermissions - this.memberRoles = role.memberRoles - additionalProperties(role.additionalProperties) + id = role.id + name = role.name + created = role.created + deletedAt = role.deletedAt + description = role.description + memberPermissions = role.memberPermissions.map { it.toMutableList() } + memberRoles = role.memberRoles.map { it.toMutableList() } + orgId = role.orgId + userId = role.userId + additionalProperties = role.additionalProperties.toMutableMap() } /** Unique identifier for the role */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the role */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - /** - * Unique id for the organization that the role belongs under - * - * A null org_id indicates a system role, which may be assigned to anybody and inherited by - * any other role, but cannot be edited. + * Sets [Builder.id] to an arbitrary JSON value. * - * It is forbidden to change the org after creating a role + * 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 orgId(orgId: String) = orgId(JsonField.of(orgId)) + fun id(id: JsonField) = apply { this.id = id } + + /** Name of the role */ + fun name(name: String) = name(JsonField.of(name)) /** - * Unique id for the organization that the role belongs under + * Sets [Builder.name] to an arbitrary JSON value. * - * A null org_id indicates a system role, which may be assigned to anybody and inherited by - * any other role, but cannot be edited. - * - * It is forbidden to change the org after creating a role + * 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. */ - @JsonProperty("org_id") - @ExcludeMissing - fun orgId(orgId: JsonField) = apply { this.orgId = orgId } - - /** Identifies the user who created the role */ - fun userId(userId: String) = userId(JsonField.of(userId)) - - /** Identifies the user who created the role */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + fun name(name: JsonField) = apply { this.name = name } /** Date of role creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) - /** Date of role creation */ - @JsonProperty("created") - @ExcludeMissing + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } - /** Name of the role */ - fun name(name: String) = name(JsonField.of(name)) + /** Date of role deletion, or null if the role is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) - /** Name of the role */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) - /** Textual description of the role */ - fun description(description: String) = description(JsonField.of(description)) + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } /** Textual description of the role */ - @JsonProperty("description") - @ExcludeMissing - fun description(description: JsonField) = apply { this.description = description } + fun description(description: String?) = description(JsonField.ofNullable(description)) - /** Date of role deletion, or null if the role is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) + /** Alias for calling [Builder.description] with `description.orElse(null)`. */ + fun description(description: Optional) = description(description.getOrNull()) - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing - fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + /** + * 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 } /** (permission, restrict_object_type) tuples which belong to this role */ - fun memberPermissions(memberPermissions: List) = - memberPermissions(JsonField.of(memberPermissions)) + fun memberPermissions(memberPermissions: List?) = + memberPermissions(JsonField.ofNullable(memberPermissions)) - /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") - @ExcludeMissing + /** Alias for calling [Builder.memberPermissions] with `memberPermissions.orElse(null)`. */ + fun memberPermissions(memberPermissions: Optional>) = + memberPermissions(memberPermissions.getOrNull()) + + /** + * Sets [Builder.memberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.memberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ fun memberPermissions(memberPermissions: JsonField>) = apply { - this.memberPermissions = memberPermissions + this.memberPermissions = memberPermissions.map { it.toMutableList() } } /** - * Ids of the roles this role inherits from + * Adds a single [MemberPermission] to [memberPermissions]. * - * An inheriting role has all the permissions contained in its member roles, as well as all - * of their inherited permissions + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun memberRoles(memberRoles: List) = memberRoles(JsonField.of(memberRoles)) + fun addMemberPermission(memberPermission: MemberPermission) = apply { + memberPermissions = + (memberPermissions ?: JsonField.of(mutableListOf())).also { + checkKnown("memberPermissions", it).add(memberPermission) + } + } /** * Ids of the roles this role inherits from @@ -312,133 +379,211 @@ private constructor( * An inheriting role has all the permissions contained in its member roles, as well as all * of their inherited permissions */ - @JsonProperty("member_roles") - @ExcludeMissing + fun memberRoles(memberRoles: List?) = memberRoles(JsonField.ofNullable(memberRoles)) + + /** Alias for calling [Builder.memberRoles] with `memberRoles.orElse(null)`. */ + fun memberRoles(memberRoles: Optional>) = memberRoles(memberRoles.getOrNull()) + + /** + * Sets [Builder.memberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.memberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun memberRoles(memberRoles: JsonField>) = apply { - this.memberRoles = memberRoles + this.memberRoles = memberRoles.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberRole(memberRole: String) = apply { + memberRoles = + (memberRoles ?: JsonField.of(mutableListOf())).also { + checkKnown("memberRoles", it).add(memberRole) + } } + /** + * Unique id for the organization that the role belongs under + * + * A null org_id indicates a system role, which may be assigned to anybody and inherited by + * any other role, but cannot be edited. + * + * It is forbidden to change the org after creating a role + */ + fun orgId(orgId: String?) = orgId(JsonField.ofNullable(orgId)) + + /** Alias for calling [Builder.orgId] with `orgId.orElse(null)`. */ + fun orgId(orgId: Optional) = orgId(orgId.getOrNull()) + + /** + * Sets [Builder.orgId] to an arbitrary JSON value. + * + * You should usually call [Builder.orgId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgId(orgId: JsonField) = apply { this.orgId = orgId } + + /** Identifies the user who created the role */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [Role]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): Role = Role( - id, - orgId, - userId, + checkRequired("id", id), + checkRequired("name", name), created, - name, - description, deletedAt, - memberPermissions.map { it.toUnmodifiable() }, - memberRoles.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + description, + (memberPermissions ?: JsonMissing.of()).map { it.toImmutable() }, + (memberRoles ?: JsonMissing.of()).map { it.toImmutable() }, + orgId, + userId, + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = MemberPermission.Builder::class) @NoAutoDetect class MemberPermission + @JsonCreator private constructor( - private val permission: JsonField, - private val restrictObjectType: JsonField, - private val additionalProperties: Map, + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - /** * Each permission permits a certain type of operation on an object in the system * * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * + * @throws BraintrustInvalidDataException 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 permission(): Permission = permission.getRequired("permission") - /** The object type that the ACL applies to */ - fun restrictObjectType(): Optional = + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) /** - * Each permission permits a certain type of operation on an object in the system + * Returns the raw JSON value of [permission]. * - * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") @ExcludeMissing fun _permission() = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") @ExcludeMissing - fun _restrictObjectType() = restrictObjectType + fun _restrictObjectType(): JsonField = restrictObjectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): MemberPermission = apply { - if (!validated) { - permission() - restrictObjectType() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): MemberPermission = apply { + if (validated) { + return@apply } - return other is MemberPermission && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - permission, - restrictObjectType, - additionalProperties, - ) - } - return hashCode + permission() + restrictObjectType() + validated = true } - override fun toString() = - "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [MemberPermission]. + * + * The following fields are required: + * ```java + * .permission() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [MemberPermission]. */ + class Builder internal constructor() { - private var permission: JsonField = JsonMissing.of() - private var restrictObjectType: JsonField = JsonMissing.of() + private var permission: JsonField? = null + private var restrictObjectType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(memberPermission: MemberPermission) = apply { - this.permission = memberPermission.permission - this.restrictObjectType = memberPermission.restrictObjectType - additionalProperties(memberPermission.additionalProperties) + permission = memberPermission.permission + restrictObjectType = memberPermission.restrictObjectType + additionalProperties = memberPermission.additionalProperties.toMutableMap() } /** @@ -450,253 +595,109 @@ private constructor( fun permission(permission: Permission) = permission(JsonField.of(permission)) /** - * Each permission permits a certain type of operation on an object in the system + * Sets [Builder.permission] to an arbitrary JSON value. * - * Permissions can be assigned to to objects on an individual basis, or grouped into - * roles + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JsonProperty("permission") - @ExcludeMissing fun permission(permission: JsonField) = apply { this.permission = permission } /** The object type that the ACL applies to */ - fun restrictObjectType(restrictObjectType: RestrictObjectType) = - restrictObjectType(JsonField.of(restrictObjectType)) + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) - /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - @ExcludeMissing - fun restrictObjectType(restrictObjectType: JsonField) = apply { + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [MemberPermission]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .permission() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): MemberPermission = MemberPermission( - permission, + checkRequired("permission", permission), restrictObjectType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + return /* spotless:off */ other is MemberPermission && permission == other.permission && restrictObjectType == other.restrictObjectType && additionalProperties == other.additionalProperties /* spotless:on */ } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(permission, restrictObjectType, additionalProperties) } + /* spotless:on */ - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) + override fun hashCode(): Int = hashCode - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } + override fun toString() = + "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + return /* spotless:off */ other is Role && id == other.id && name == other.name && created == other.created && deletedAt == other.deletedAt && description == other.description && memberPermissions == other.memberPermissions && memberRoles == other.memberRoles && orgId == other.orgId && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, created, deletedAt, description, memberPermissions, memberRoles, orgId, userId, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "Role{id=$id, name=$name, created=$created, deletedAt=$deletedAt, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgId=$orgId, userId=$userId, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleCreateParams.kt index 492f4055..d33aa0b9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleCreateParams.kt @@ -2,173 +2,358 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new role. If there is an existing role with the same name as the one specified in the + * request, will return the existing role unmodified + */ class RoleCreateParams -constructor( - private val name: String, - private val description: String?, - private val memberPermissions: List?, - private val memberRoles: List?, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun description(): Optional = Optional.ofNullable(description) - - fun memberPermissions(): Optional> = - Optional.ofNullable(memberPermissions) - - fun memberRoles(): Optional> = Optional.ofNullable(memberRoles) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): RoleCreateBody { - return RoleCreateBody( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the role + * + * @throws BraintrustInvalidDataException 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() + + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * (permission, restrict_object_type) tuples which belong to this role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberPermissions(): Optional> = body.memberPermissions() + + /** + * Ids of the roles this role inherits from + * + * An inheriting role has all the permissions contained in its member roles, as well as all of + * their inherited permissions + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberRoles(): Optional> = body.memberRoles() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * role belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [memberPermissions]. + * + * Unlike [memberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _memberPermissions(): JsonField> = body._memberPermissions() + + /** + * Returns the raw JSON value of [memberRoles]. + * + * Unlike [memberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberRoles(): JsonField> = body._memberRoles() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = RoleCreateBody.Builder::class) @NoAutoDetect - class RoleCreateBody - internal constructor( - private val name: String?, - private val description: String?, - private val memberPermissions: List?, - private val memberRoles: List?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_permissions") + @ExcludeMissing + private val memberPermissions: JsonField> = JsonMissing.of(), + @JsonProperty("member_roles") + @ExcludeMissing + private val memberRoles: JsonField> = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the role */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the role + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the role */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") - fun memberPermissions(): List? = memberPermissions + /** + * (permission, restrict_object_type) tuples which belong to this role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun memberPermissions(): Optional> = + Optional.ofNullable(memberPermissions.getNullable("member_permissions")) /** * Ids of the roles this role inherits from * * An inheriting role has all the permissions contained in its member roles, as well as all * of their inherited permissions + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("member_roles") fun memberRoles(): List? = memberRoles + fun memberRoles(): Optional> = + Optional.ofNullable(memberRoles.getNullable("member_roles")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @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 [memberPermissions]. + * + * Unlike [memberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("member_permissions") + @ExcludeMissing + fun _memberPermissions(): JsonField> = memberPermissions + + /** + * Returns the raw JSON value of [memberRoles]. + * + * Unlike [memberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_roles") + @ExcludeMissing + fun _memberRoles(): JsonField> = memberRoles + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is RoleCreateBody && - this.name == other.name && - this.description == other.description && - this.memberPermissions == other.memberPermissions && - this.memberRoles == other.memberRoles && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalProperties, - ) - } - return hashCode + name() + description() + memberPermissions().ifPresent { it.forEach { it.validate() } } + memberRoles() + orgName() + validated = true } - override fun toString() = - "RoleCreateBody{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberPermissions: List? = null - private var memberRoles: List? = null - private var orgName: String? = null + private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var memberPermissions: JsonField>? = null + private var memberRoles: JsonField>? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(roleCreateBody: RoleCreateBody) = apply { - this.name = roleCreateBody.name - this.description = roleCreateBody.description - this.memberPermissions = roleCreateBody.memberPermissions - this.memberRoles = roleCreateBody.memberRoles - this.orgName = roleCreateBody.orgName - additionalProperties(roleCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + description = body.description + memberPermissions = body.memberPermissions.map { it.toMutableList() } + memberRoles = body.memberRoles.map { it.toMutableList() } + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the role */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Textual description of the role */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") - fun memberPermissions(memberPermissions: List) = apply { - this.memberPermissions = memberPermissions + fun memberPermissions(memberPermissions: List?) = + memberPermissions(JsonField.ofNullable(memberPermissions)) + + /** + * Alias for calling [Builder.memberPermissions] with `memberPermissions.orElse(null)`. + */ + fun memberPermissions(memberPermissions: Optional>) = + memberPermissions(memberPermissions.getOrNull()) + + /** + * Sets [Builder.memberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.memberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun memberPermissions(memberPermissions: JsonField>) = apply { + this.memberPermissions = memberPermissions.map { it.toMutableList() } + } + + /** + * Adds a single [MemberPermission] to [memberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberPermission(memberPermission: MemberPermission) = apply { + memberPermissions = + (memberPermissions ?: JsonField.of(mutableListOf())).also { + checkKnown("memberPermissions", it).add(memberPermission) + } } /** @@ -177,127 +362,198 @@ constructor( * An inheriting role has all the permissions contained in its member roles, as well as * all of their inherited permissions */ - @JsonProperty("member_roles") - fun memberRoles(memberRoles: List) = apply { this.memberRoles = memberRoles } + fun memberRoles(memberRoles: List?) = + memberRoles(JsonField.ofNullable(memberRoles)) + + /** Alias for calling [Builder.memberRoles] with `memberRoles.orElse(null)`. */ + fun memberRoles(memberRoles: Optional>) = + memberRoles(memberRoles.getOrNull()) + + /** + * Sets [Builder.memberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.memberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberRoles(memberRoles: JsonField>) = apply { + this.memberRoles = memberRoles.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberRole(memberRole: String) = apply { + memberRoles = + (memberRoles ?: JsonField.of(mutableListOf())).also { + checkKnown("memberRoles", it).add(memberRole) + } + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): RoleCreateBody = - RoleCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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, - memberPermissions?.toUnmodifiable(), - memberRoles?.toUnmodifiable(), + (memberPermissions ?: JsonMissing.of()).map { it.toImmutable() }, + (memberRoles ?: JsonMissing.of()).map { it.toImmutable() }, orgName, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && description == other.description && memberPermissions == other.memberPermissions && memberRoles == other.memberRoles && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is RoleCreateParams && - this.name == other.name && - this.description == other.description && - this.memberPermissions == other.memberPermissions && - this.memberRoles == other.memberRoles && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, description, memberPermissions, memberRoles, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "RoleCreateParams{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RoleCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleCreateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberPermissions: MutableList = mutableListOf() - private var memberRoles: MutableList = mutableListOf() - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(roleCreateParams: RoleCreateParams) = apply { - this.name = roleCreateParams.name - this.description = roleCreateParams.description - this.memberPermissions(roleCreateParams.memberPermissions ?: listOf()) - this.memberRoles(roleCreateParams.memberRoles ?: listOf()) - this.orgName = roleCreateParams.orgName - additionalQueryParams(roleCreateParams.additionalQueryParams) - additionalHeaders(roleCreateParams.additionalHeaders) - additionalBodyProperties(roleCreateParams.additionalBodyProperties) + body = roleCreateParams.body.toBuilder() + additionalHeaders = roleCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = roleCreateParams.additionalQueryParams.toBuilder() } /** Name of the role */ - fun name(name: String) = apply { this.name = 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) } /** Textual description of the role */ - fun description(description: String) = apply { this.description = description } + 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) } /** (permission, restrict_object_type) tuples which belong to this role */ - fun memberPermissions(memberPermissions: List) = apply { - this.memberPermissions.clear() - this.memberPermissions.addAll(memberPermissions) + fun memberPermissions(memberPermissions: List?) = apply { + body.memberPermissions(memberPermissions) } - /** (permission, restrict_object_type) tuples which belong to this role */ + /** Alias for calling [Builder.memberPermissions] with `memberPermissions.orElse(null)`. */ + fun memberPermissions(memberPermissions: Optional>) = + memberPermissions(memberPermissions.getOrNull()) + + /** + * Sets [Builder.memberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.memberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun memberPermissions(memberPermissions: JsonField>) = apply { + body.memberPermissions(memberPermissions) + } + + /** + * Adds a single [MemberPermission] to [memberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addMemberPermission(memberPermission: MemberPermission) = apply { - this.memberPermissions.add(memberPermission) + body.addMemberPermission(memberPermission) } /** @@ -306,163 +562,275 @@ constructor( * An inheriting role has all the permissions contained in its member roles, as well as all * of their inherited permissions */ - fun memberRoles(memberRoles: List) = apply { - this.memberRoles.clear() - this.memberRoles.addAll(memberRoles) + fun memberRoles(memberRoles: List?) = apply { body.memberRoles(memberRoles) } + + /** Alias for calling [Builder.memberRoles] with `memberRoles.orElse(null)`. */ + fun memberRoles(memberRoles: Optional>) = memberRoles(memberRoles.getOrNull()) + + /** + * Sets [Builder.memberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.memberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberRoles(memberRoles: JsonField>) = apply { + body.memberRoles(memberRoles) } /** - * Ids of the roles this role inherits from + * Adds a single [String] to [memberRoles]. * - * An inheriting role has all the permissions contained in its member roles, as well as all - * of their inherited permissions + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addMemberRole(memberRole: String) = apply { this.memberRoles.add(memberRole) } + fun addMemberRole(memberRole: String) = apply { body.addMemberRole(memberRole) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [RoleCreateParams]. + * + * 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(): RoleCreateParams = - RoleCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - description, - if (memberPermissions.size == 0) null else memberPermissions.toUnmodifiable(), - if (memberRoles.size == 0) null else memberRoles.toUnmodifiable(), - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) + RoleCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) } - @JsonDeserialize(builder = MemberPermission.Builder::class) @NoAutoDetect class MemberPermission + @JsonCreator private constructor( - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val additionalProperties: Map, + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * Each permission permits a certain type of operation on an object in the system * * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * + * @throws BraintrustInvalidDataException 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 permission(): Permission = permission.getRequired("permission") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") fun permission(): Permission? = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): MemberPermission = apply { + if (validated) { + return@apply } - return other is MemberPermission && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - permission, - restrictObjectType, - additionalProperties, - ) - } - return hashCode + permission() + restrictObjectType() + validated = true } - override fun toString() = - "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [MemberPermission]. + * + * The following fields are required: + * ```java + * .permission() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [MemberPermission]. */ + class Builder internal constructor() { - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null + private var permission: JsonField? = null + private var restrictObjectType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(memberPermission: MemberPermission) = apply { - this.permission = memberPermission.permission - this.restrictObjectType = memberPermission.restrictObjectType - additionalProperties(memberPermission.additionalProperties) + permission = memberPermission.permission + restrictObjectType = memberPermission.restrictObjectType + additionalProperties = memberPermission.additionalProperties.toMutableMap() } /** @@ -471,240 +839,108 @@ constructor( * Permissions can be assigned to to objects on an individual basis, or grouped into * roles */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun permission(permission: Permission) = permission(JsonField.of(permission)) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [MemberPermission]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .permission() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): MemberPermission = MemberPermission( - checkNotNull(permission) { "`permission` is required but was not set" }, + checkRequired("permission", permission), restrictObjectType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) + return /* spotless:off */ other is MemberPermission && permission == other.permission && restrictObjectType == other.restrictObjectType && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(permission, restrictObjectType, additionalProperties) } + /* spotless:on */ - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) + override fun hashCode(): Int = hashCode - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) + override fun toString() = + "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + } - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + return /* spotless:off */ other is RoleCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "RoleCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleDeleteParams.kt index 8e8f313f..9136f6ee 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleDeleteParams.kt @@ -4,29 +4,39 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable import java.util.Objects import java.util.Optional +/** Delete a role object by its id */ class RoleDeleteParams -constructor( +private constructor( private val roleId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, private val additionalBodyProperties: Map, -) { +) : Params { + /** Role id */ fun roleId(): String = roleId + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + @JvmSynthetic - internal fun getBody(): Optional> { - return Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - } + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -35,109 +45,146 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RoleDeleteParams && - this.roleId == other.roleId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } - - override fun hashCode(): Int { - return Objects.hash( - roleId, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } - - override fun toString() = - "RoleDeleteParams{roleId=$roleId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RoleDeleteParams]. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var roleId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(roleDeleteParams: RoleDeleteParams) = apply { - this.roleId = roleDeleteParams.roleId - additionalQueryParams(roleDeleteParams.additionalQueryParams) - additionalHeaders(roleDeleteParams.additionalHeaders) - additionalBodyProperties(roleDeleteParams.additionalBodyProperties) + roleId = roleDeleteParams.roleId + additionalHeaders = roleDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = roleDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = roleDeleteParams.additionalBodyProperties.toMutableMap() } /** Role id */ fun roleId(roleId: String) = apply { this.roleId = roleId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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) + } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + putAllAdditionalBodyProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + additionalBodyProperties.put(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = @@ -145,12 +192,45 @@ constructor( this.additionalBodyProperties.putAll(additionalBodyProperties) } + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [RoleDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RoleDeleteParams = RoleDeleteParams( - checkNotNull(roleId) { "`roleId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("roleId", roleId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RoleDeleteParams && roleId == other.roleId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(roleId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "RoleDeleteParams{roleId=$roleId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPage.kt index d49ae5dc..9cae9580 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.RoleService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all roles. The roles are sorted by creation date, with the most recently-created roles + * coming first + */ class RoleListPage private constructor( private val rolesService: RoleService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is RoleListPage && - this.rolesService == other.rolesService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is RoleListPage && rolesService == other.rolesService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - rolesService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(rolesService, params, response) /* spotless:on */ override fun toString() = "RoleListPage{rolesService=$rolesService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(rolesService: RoleService, params: RoleListParams, response: Response) = - RoleListPage( - rolesService, - params, - response, - ) + RoleListPage(rolesService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "RoleListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [RoleListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: RoleListPage, - ) : Iterable { + class AutoPager(private val firstPage: RoleListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPageAsync.kt index a53c7f0f..8e13282e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.RoleServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all roles. The roles are sorted by creation date, with the most recently-created roles + * coming first + */ class RoleListPageAsync private constructor( private val rolesService: RoleServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is RoleListPageAsync && - this.rolesService == other.rolesService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is RoleListPageAsync && rolesService == other.rolesService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - rolesService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(rolesService, params, response) /* spotless:on */ override fun toString() = "RoleListPageAsync{rolesService=$rolesService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(rolesService: RoleServiceAsync, params: RoleListParams, response: Response) = - RoleListPageAsync( - rolesService, - params, - response, - ) + RoleListPageAsync(rolesService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "RoleListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [RoleListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: RoleListPageAsync, - ) { + class AutoPager(private val firstPage: RoleListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (Role) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListParams.kt index 33910b59..333d1d99 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,91 +20,99 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all roles. The roles are sorted by creation date, with the most recently-created roles + * coming first + */ class RoleListParams -constructor( +private constructor( private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val orgName: String?, private val roleName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** Name of the role to search for */ fun roleName(): Optional = Optional.ofNullable(roleName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.roleName?.let { params.put("role_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RoleListParams && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.roleName == other.roleName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - endingBefore, - ids, - limit, - orgName, - roleName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "RoleListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, roleName=$roleName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + roleName?.let { put("role_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): RoleListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [RoleListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var endingBefore: String? = null private var ids: Ids? = null @@ -111,19 +120,19 @@ constructor( private var orgName: String? = null private var roleName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(roleListParams: RoleListParams) = apply { - this.endingBefore = roleListParams.endingBefore - this.ids = roleListParams.ids - this.limit = roleListParams.limit - this.orgName = roleListParams.orgName - this.roleName = roleListParams.roleName - this.startingAfter = roleListParams.startingAfter - additionalQueryParams(roleListParams.additionalQueryParams) - additionalHeaders(roleListParams.additionalHeaders) + endingBefore = roleListParams.endingBefore + ids = roleListParams.ids + limit = roleListParams.limit + orgName = roleListParams.orgName + roleName = roleListParams.roleName + startingAfter = roleListParams.startingAfter + additionalHeaders = roleListParams.additionalHeaders.toBuilder() + additionalQueryParams = roleListParams.additionalQueryParams.toBuilder() } /** @@ -133,34 +142,50 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** Name of the role to search for */ - fun roleName(roleName: String) = apply { this.roleName = roleName } + fun roleName(roleName: String?) = apply { this.roleName = roleName } + + /** Alias for calling [Builder.roleName] with `roleName.orElse(null)`. */ + fun roleName(roleName: Optional) = roleName(roleName.getOrNull()) /** * Pagination cursor id. @@ -169,48 +194,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [RoleListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): RoleListParams = RoleListParams( endingBefore, @@ -219,11 +311,15 @@ constructor( orgName, roleName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -233,8 +329,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -257,35 +351,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -294,21 +376,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -320,12 +413,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -336,4 +429,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RoleListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && roleName == other.roleName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, roleName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "RoleListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, roleName=$roleName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleReplaceParams.kt index 68772fb6..97635d9d 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleReplaceParams.kt @@ -2,173 +2,358 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace role. If there is an existing role with the same name as the one specified in + * the request, will replace the existing role with the provided fields + */ class RoleReplaceParams -constructor( - private val name: String, - private val description: String?, - private val memberPermissions: List?, - private val memberRoles: List?, - private val orgName: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun description(): Optional = Optional.ofNullable(description) - - fun memberPermissions(): Optional> = - Optional.ofNullable(memberPermissions) - - fun memberRoles(): Optional> = Optional.ofNullable(memberRoles) - - fun orgName(): Optional = Optional.ofNullable(orgName) - - @JvmSynthetic - internal fun getBody(): RoleReplaceBody { - return RoleReplaceBody( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the role + * + * @throws BraintrustInvalidDataException 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() + + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * (permission, restrict_object_type) tuples which belong to this role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberPermissions(): Optional> = body.memberPermissions() + + /** + * Ids of the roles this role inherits from + * + * An inheriting role has all the permissions contained in its member roles, as well as all of + * their inherited permissions + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun memberRoles(): Optional> = body.memberRoles() + + /** + * For nearly all users, this parameter should be unnecessary. But in the rare case that your + * API key belongs to multiple organizations, you may specify the name of the organization the + * role belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun orgName(): Optional = body.orgName() + + /** + * 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 [memberPermissions]. + * + * Unlike [memberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _memberPermissions(): JsonField> = body._memberPermissions() + + /** + * Returns the raw JSON value of [memberRoles]. + * + * Unlike [memberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _memberRoles(): JsonField> = body._memberRoles() + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _orgName(): JsonField = body._orgName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JsonDeserialize(builder = RoleReplaceBody.Builder::class) @NoAutoDetect - class RoleReplaceBody - internal constructor( - private val name: String?, - private val description: String?, - private val memberPermissions: List?, - private val memberRoles: List?, - private val orgName: String?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("member_permissions") + @ExcludeMissing + private val memberPermissions: JsonField> = JsonMissing.of(), + @JsonProperty("member_roles") + @ExcludeMissing + private val memberRoles: JsonField> = JsonMissing.of(), + @JsonProperty("org_name") + @ExcludeMissing + private val orgName: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the role */ - @JsonProperty("name") fun name(): String? = name + /** + * Name of the role + * + * @throws BraintrustInvalidDataException 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") - /** Textual description of the role */ - @JsonProperty("description") fun description(): String? = description + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) - /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") - fun memberPermissions(): List? = memberPermissions + /** + * (permission, restrict_object_type) tuples which belong to this role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun memberPermissions(): Optional> = + Optional.ofNullable(memberPermissions.getNullable("member_permissions")) /** * Ids of the roles this role inherits from * * An inheriting role has all the permissions contained in its member roles, as well as all * of their inherited permissions + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - @JsonProperty("member_roles") fun memberRoles(): List? = memberRoles + fun memberRoles(): Optional> = + Optional.ofNullable(memberRoles.getNullable("member_roles")) /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun orgName(): Optional = Optional.ofNullable(orgName.getNullable("org_name")) + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("org_name") fun orgName(): String? = orgName + @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 [memberPermissions]. + * + * Unlike [memberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("member_permissions") + @ExcludeMissing + fun _memberPermissions(): JsonField> = memberPermissions + + /** + * Returns the raw JSON value of [memberRoles]. + * + * Unlike [memberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("member_roles") + @ExcludeMissing + fun _memberRoles(): JsonField> = memberRoles + + /** + * Returns the raw JSON value of [orgName]. + * + * Unlike [orgName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("org_name") @ExcludeMissing fun _orgName(): JsonField = orgName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is RoleReplaceBody && - this.name == other.name && - this.description == other.description && - this.memberPermissions == other.memberPermissions && - this.memberRoles == other.memberRoles && - this.orgName == other.orgName && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalProperties, - ) - } - return hashCode + name() + description() + memberPermissions().ifPresent { it.forEach { it.validate() } } + memberRoles() + orgName() + validated = true } - override fun toString() = - "RoleReplaceBody{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalProperties=$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() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberPermissions: List? = null - private var memberRoles: List? = null - private var orgName: String? = null + private var name: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var memberPermissions: JsonField>? = null + private var memberRoles: JsonField>? = null + private var orgName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(roleReplaceBody: RoleReplaceBody) = apply { - this.name = roleReplaceBody.name - this.description = roleReplaceBody.description - this.memberPermissions = roleReplaceBody.memberPermissions - this.memberRoles = roleReplaceBody.memberRoles - this.orgName = roleReplaceBody.orgName - additionalProperties(roleReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + description = body.description + memberPermissions = body.memberPermissions.map { it.toMutableList() } + memberRoles = body.memberRoles.map { it.toMutableList() } + orgName = body.orgName + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the role */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** Textual description of the role */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** (permission, restrict_object_type) tuples which belong to this role */ - @JsonProperty("member_permissions") - fun memberPermissions(memberPermissions: List) = apply { - this.memberPermissions = memberPermissions + fun memberPermissions(memberPermissions: List?) = + memberPermissions(JsonField.ofNullable(memberPermissions)) + + /** + * Alias for calling [Builder.memberPermissions] with `memberPermissions.orElse(null)`. + */ + fun memberPermissions(memberPermissions: Optional>) = + memberPermissions(memberPermissions.getOrNull()) + + /** + * Sets [Builder.memberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.memberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun memberPermissions(memberPermissions: JsonField>) = apply { + this.memberPermissions = memberPermissions.map { it.toMutableList() } + } + + /** + * Adds a single [MemberPermission] to [memberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberPermission(memberPermission: MemberPermission) = apply { + memberPermissions = + (memberPermissions ?: JsonField.of(mutableListOf())).also { + checkKnown("memberPermissions", it).add(memberPermission) + } } /** @@ -177,127 +362,198 @@ constructor( * An inheriting role has all the permissions contained in its member roles, as well as * all of their inherited permissions */ - @JsonProperty("member_roles") - fun memberRoles(memberRoles: List) = apply { this.memberRoles = memberRoles } + fun memberRoles(memberRoles: List?) = + memberRoles(JsonField.ofNullable(memberRoles)) + + /** Alias for calling [Builder.memberRoles] with `memberRoles.orElse(null)`. */ + fun memberRoles(memberRoles: Optional>) = + memberRoles(memberRoles.getOrNull()) + + /** + * Sets [Builder.memberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.memberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberRoles(memberRoles: JsonField>) = apply { + this.memberRoles = memberRoles.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [memberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMemberRole(memberRole: String) = apply { + memberRoles = + (memberRoles ?: JsonField.of(mutableListOf())).also { + checkKnown("memberRoles", it).add(memberRole) + } + } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. */ - @JsonProperty("org_name") - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = orgName(JsonField.ofNullable(orgName)) + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun orgName(orgName: JsonField) = apply { this.orgName = orgName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): RoleReplaceBody = - RoleReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, + 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, - memberPermissions?.toUnmodifiable(), - memberRoles?.toUnmodifiable(), + (memberPermissions ?: JsonMissing.of()).map { it.toImmutable() }, + (memberRoles ?: JsonMissing.of()).map { it.toImmutable() }, orgName, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && description == other.description && memberPermissions == other.memberPermissions && memberRoles == other.memberRoles && orgName == other.orgName && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is RoleReplaceParams && - this.name == other.name && - this.description == other.description && - this.memberPermissions == other.memberPermissions && - this.memberRoles == other.memberRoles && - this.orgName == other.orgName && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, description, memberPermissions, memberRoles, orgName, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - description, - memberPermissions, - memberRoles, - orgName, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "RoleReplaceParams{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, description=$description, memberPermissions=$memberPermissions, memberRoles=$memberRoles, orgName=$orgName, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RoleReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleReplaceParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var name: String? = null - private var description: String? = null - private var memberPermissions: MutableList = mutableListOf() - private var memberRoles: MutableList = mutableListOf() - private var orgName: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(roleReplaceParams: RoleReplaceParams) = apply { - this.name = roleReplaceParams.name - this.description = roleReplaceParams.description - this.memberPermissions(roleReplaceParams.memberPermissions ?: listOf()) - this.memberRoles(roleReplaceParams.memberRoles ?: listOf()) - this.orgName = roleReplaceParams.orgName - additionalQueryParams(roleReplaceParams.additionalQueryParams) - additionalHeaders(roleReplaceParams.additionalHeaders) - additionalBodyProperties(roleReplaceParams.additionalBodyProperties) + body = roleReplaceParams.body.toBuilder() + additionalHeaders = roleReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = roleReplaceParams.additionalQueryParams.toBuilder() } /** Name of the role */ - fun name(name: String) = apply { this.name = 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) } /** Textual description of the role */ - fun description(description: String) = apply { this.description = description } + 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) } /** (permission, restrict_object_type) tuples which belong to this role */ - fun memberPermissions(memberPermissions: List) = apply { - this.memberPermissions.clear() - this.memberPermissions.addAll(memberPermissions) + fun memberPermissions(memberPermissions: List?) = apply { + body.memberPermissions(memberPermissions) } - /** (permission, restrict_object_type) tuples which belong to this role */ + /** Alias for calling [Builder.memberPermissions] with `memberPermissions.orElse(null)`. */ + fun memberPermissions(memberPermissions: Optional>) = + memberPermissions(memberPermissions.getOrNull()) + + /** + * Sets [Builder.memberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.memberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun memberPermissions(memberPermissions: JsonField>) = apply { + body.memberPermissions(memberPermissions) + } + + /** + * Adds a single [MemberPermission] to [memberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addMemberPermission(memberPermission: MemberPermission) = apply { - this.memberPermissions.add(memberPermission) + body.addMemberPermission(memberPermission) } /** @@ -306,163 +562,279 @@ constructor( * An inheriting role has all the permissions contained in its member roles, as well as all * of their inherited permissions */ - fun memberRoles(memberRoles: List) = apply { - this.memberRoles.clear() - this.memberRoles.addAll(memberRoles) + fun memberRoles(memberRoles: List?) = apply { body.memberRoles(memberRoles) } + + /** Alias for calling [Builder.memberRoles] with `memberRoles.orElse(null)`. */ + fun memberRoles(memberRoles: Optional>) = memberRoles(memberRoles.getOrNull()) + + /** + * Sets [Builder.memberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.memberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun memberRoles(memberRoles: JsonField>) = apply { + body.memberRoles(memberRoles) } /** - * Ids of the roles this role inherits from + * Adds a single [String] to [memberRoles]. * - * An inheriting role has all the permissions contained in its member roles, as well as all - * of their inherited permissions + * @throws IllegalStateException if the field was previously set to a non-list. */ - fun addMemberRole(memberRole: String) = apply { this.memberRoles.add(memberRole) } + fun addMemberRole(memberRole: String) = apply { body.addMemberRole(memberRole) } /** * For nearly all users, this parameter should be unnecessary. But in the rare case that * your API key belongs to multiple organizations, you may specify the name of the * organization the role belongs in. */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { body.orgName(orgName) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + /** + * Sets [Builder.orgName] to an arbitrary JSON value. + * + * You should usually call [Builder.orgName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun orgName(orgName: JsonField) = apply { body.orgName(orgName) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [RoleReplaceParams]. + * + * 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(): RoleReplaceParams = RoleReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - description, - if (memberPermissions.size == 0) null else memberPermissions.toUnmodifiable(), - if (memberRoles.size == 0) null else memberRoles.toUnmodifiable(), - orgName, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } - @JsonDeserialize(builder = MemberPermission.Builder::class) @NoAutoDetect class MemberPermission + @JsonCreator private constructor( - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val additionalProperties: Map, + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * Each permission permits a certain type of operation on an object in the system * * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * + * @throws BraintrustInvalidDataException 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 permission(): Permission = permission.getRequired("permission") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") fun permission(): Permission? = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): MemberPermission = apply { + if (validated) { + return@apply } - return other is MemberPermission && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - permission, - restrictObjectType, - additionalProperties, - ) - } - return hashCode + permission() + restrictObjectType() + validated = true } - override fun toString() = - "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [MemberPermission]. + * + * The following fields are required: + * ```java + * .permission() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [MemberPermission]. */ + class Builder internal constructor() { - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null + private var permission: JsonField? = null + private var restrictObjectType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(memberPermission: MemberPermission) = apply { - this.permission = memberPermission.permission - this.restrictObjectType = memberPermission.restrictObjectType - additionalProperties(memberPermission.additionalProperties) + permission = memberPermission.permission + restrictObjectType = memberPermission.restrictObjectType + additionalProperties = memberPermission.additionalProperties.toMutableMap() } /** @@ -471,240 +843,108 @@ constructor( * Permissions can be assigned to to objects on an individual basis, or grouped into * roles */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun permission(permission: Permission) = permission(JsonField.of(permission)) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [MemberPermission]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .permission() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): MemberPermission = MemberPermission( - checkNotNull(permission) { "`permission` is required but was not set" }, + checkRequired("permission", permission), restrictObjectType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) + return /* spotless:off */ other is MemberPermission && permission == other.permission && restrictObjectType == other.restrictObjectType && additionalProperties == other.additionalProperties /* spotless:on */ + } - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(permission, restrictObjectType, additionalProperties) } + /* spotless:on */ - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) + override fun hashCode(): Int = hashCode - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) + override fun toString() = + "MemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + } - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + return /* spotless:off */ other is RoleReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "RoleReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleRetrieveParams.kt index 9f1fbfef..1afba4b5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a role object by its id */ class RoleRetrieveParams -constructor( +private constructor( private val roleId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Role id */ fun roleId(): String = roleId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RoleRetrieveParams && - this.roleId == other.roleId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - roleId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "RoleRetrieveParams{roleId=$roleId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RoleRetrieveParams]. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var roleId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(roleRetrieveParams: RoleRetrieveParams) = apply { - this.roleId = roleRetrieveParams.roleId - additionalQueryParams(roleRetrieveParams.additionalQueryParams) - additionalHeaders(roleRetrieveParams.additionalHeaders) + roleId = roleRetrieveParams.roleId + additionalHeaders = roleRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = roleRetrieveParams.additionalQueryParams.toBuilder() } /** Role id */ fun roleId(roleId: String) = apply { this.roleId = roleId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [RoleRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RoleRetrieveParams = RoleRetrieveParams( - checkNotNull(roleId) { "`roleId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("roleId", roleId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is RoleRetrieveParams && roleId == other.roleId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(roleId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "RoleRetrieveParams{roleId=$roleId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleUpdateParams.kt index 80f56383..da629d22 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/RoleUpdateParams.kt @@ -2,68 +2,149 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a role object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class RoleUpdateParams -constructor( +private constructor( private val roleId: String, - private val addMemberPermissions: List?, - private val addMemberRoles: List?, - private val description: String?, - private val name: String?, - private val removeMemberPermissions: List?, - private val removeMemberRoles: List?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** Role id */ fun roleId(): String = roleId - fun addMemberPermissions(): Optional> = - Optional.ofNullable(addMemberPermissions) - - fun addMemberRoles(): Optional> = Optional.ofNullable(addMemberRoles) - - fun description(): Optional = Optional.ofNullable(description) - - fun name(): Optional = Optional.ofNullable(name) - + /** + * A list of permissions to add to the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun addMemberPermissions(): Optional> = body.addMemberPermissions() + + /** + * A list of role IDs to add to the role's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun addMemberRoles(): Optional> = body.addMemberRoles() + + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * A list of permissions to remove from the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun removeMemberPermissions(): Optional> = - Optional.ofNullable(removeMemberPermissions) - - fun removeMemberRoles(): Optional> = Optional.ofNullable(removeMemberRoles) - - @JvmSynthetic - internal fun getBody(): RoleUpdateBody { - return RoleUpdateBody( - addMemberPermissions, - addMemberRoles, - description, - name, - removeMemberPermissions, - removeMemberRoles, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + body.removeMemberPermissions() + + /** + * A list of role IDs to remove from the role's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun removeMemberRoles(): Optional> = body.removeMemberRoles() + + /** + * Returns the raw JSON value of [addMemberPermissions]. + * + * Unlike [addMemberPermissions], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _addMemberPermissions(): JsonField> = body._addMemberPermissions() + + /** + * Returns the raw JSON value of [addMemberRoles]. + * + * Unlike [addMemberRoles], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _addMemberRoles(): JsonField> = body._addMemberRoles() + + /** + * 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 [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 [removeMemberPermissions]. + * + * Unlike [removeMemberPermissions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + fun _removeMemberPermissions(): JsonField> = + body._removeMemberPermissions() + + /** + * Returns the raw JSON value of [removeMemberRoles]. + * + * Unlike [removeMemberRoles], this method doesn't throw if the JSON field has an unexpected + * type. + */ + fun _removeMemberRoles(): JsonField> = body._removeMemberRoles() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -72,437 +153,836 @@ constructor( } } - @JsonDeserialize(builder = RoleUpdateBody.Builder::class) @NoAutoDetect - class RoleUpdateBody - internal constructor( - private val addMemberPermissions: List?, - private val addMemberRoles: List?, - private val description: String?, - private val name: String?, - private val removeMemberPermissions: List?, - private val removeMemberRoles: List?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("add_member_permissions") + @ExcludeMissing + private val addMemberPermissions: JsonField> = JsonMissing.of(), + @JsonProperty("add_member_roles") + @ExcludeMissing + private val addMemberRoles: JsonField> = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("remove_member_permissions") + @ExcludeMissing + private val removeMemberPermissions: JsonField> = + JsonMissing.of(), + @JsonProperty("remove_member_roles") + @ExcludeMissing + private val removeMemberRoles: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 + /** + * A list of permissions to add to the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun addMemberPermissions(): Optional> = + Optional.ofNullable(addMemberPermissions.getNullable("add_member_permissions")) - /** A list of permissions to add to the role */ + /** + * A list of role IDs to add to the role's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun addMemberRoles(): Optional> = + Optional.ofNullable(addMemberRoles.getNullable("add_member_roles")) + + /** + * Textual description of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * A list of permissions to remove from the role + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeMemberPermissions(): Optional> = + Optional.ofNullable(removeMemberPermissions.getNullable("remove_member_permissions")) + + /** + * A list of role IDs to remove from the role's inheriting-from set + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun removeMemberRoles(): Optional> = + Optional.ofNullable(removeMemberRoles.getNullable("remove_member_roles")) + + /** + * Returns the raw JSON value of [addMemberPermissions]. + * + * Unlike [addMemberPermissions], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("add_member_permissions") - fun addMemberPermissions(): List? = addMemberPermissions + @ExcludeMissing + fun _addMemberPermissions(): JsonField> = addMemberPermissions - /** A list of role IDs to add to the role's inheriting-from set */ - @JsonProperty("add_member_roles") fun addMemberRoles(): List? = addMemberRoles + /** + * Returns the raw JSON value of [addMemberRoles]. + * + * Unlike [addMemberRoles], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("add_member_roles") + @ExcludeMissing + fun _addMemberRoles(): JsonField> = addMemberRoles - /** Textual description of the role */ - @JsonProperty("description") fun description(): String? = description + /** + * 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 - /** Name of the role */ - @JsonProperty("name") fun name(): String? = name + /** + * 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 - /** A list of permissions to remove from the role */ + /** + * Returns the raw JSON value of [removeMemberPermissions]. + * + * Unlike [removeMemberPermissions], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("remove_member_permissions") - fun removeMemberPermissions(): List? = removeMemberPermissions + @ExcludeMissing + fun _removeMemberPermissions(): JsonField> = + removeMemberPermissions - /** A list of role IDs to remove from the role's inheriting-from set */ + /** + * Returns the raw JSON value of [removeMemberRoles]. + * + * Unlike [removeMemberRoles], this method doesn't throw if the JSON field has an unexpected + * type. + */ @JsonProperty("remove_member_roles") - fun removeMemberRoles(): List? = removeMemberRoles + @ExcludeMissing + fun _removeMemberRoles(): JsonField> = removeMemberRoles @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is RoleUpdateBody && - this.addMemberPermissions == other.addMemberPermissions && - this.addMemberRoles == other.addMemberRoles && - this.description == other.description && - this.name == other.name && - this.removeMemberPermissions == other.removeMemberPermissions && - this.removeMemberRoles == other.removeMemberRoles && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - addMemberPermissions, - addMemberRoles, - description, - name, - removeMemberPermissions, - removeMemberRoles, - additionalProperties, - ) - } - return hashCode + addMemberPermissions().ifPresent { it.forEach { it.validate() } } + addMemberRoles() + description() + name() + removeMemberPermissions().ifPresent { it.forEach { it.validate() } } + removeMemberRoles() + validated = true } - override fun toString() = - "RoleUpdateBody{addMemberPermissions=$addMemberPermissions, addMemberRoles=$addMemberRoles, description=$description, name=$name, removeMemberPermissions=$removeMemberPermissions, removeMemberRoles=$removeMemberRoles, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Body]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var addMemberPermissions: List? = null - private var addMemberRoles: List? = null - private var description: String? = null - private var name: String? = null - private var removeMemberPermissions: List? = null - private var removeMemberRoles: List? = null + private var addMemberPermissions: JsonField>? = null + private var addMemberRoles: JsonField>? = null + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var removeMemberPermissions: JsonField>? = + null + private var removeMemberRoles: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(roleUpdateBody: RoleUpdateBody) = apply { - this.addMemberPermissions = roleUpdateBody.addMemberPermissions - this.addMemberRoles = roleUpdateBody.addMemberRoles - this.description = roleUpdateBody.description - this.name = roleUpdateBody.name - this.removeMemberPermissions = roleUpdateBody.removeMemberPermissions - this.removeMemberRoles = roleUpdateBody.removeMemberRoles - additionalProperties(roleUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + addMemberPermissions = body.addMemberPermissions.map { it.toMutableList() } + addMemberRoles = body.addMemberRoles.map { it.toMutableList() } + description = body.description + name = body.name + removeMemberPermissions = body.removeMemberPermissions.map { it.toMutableList() } + removeMemberRoles = body.removeMemberRoles.map { it.toMutableList() } + additionalProperties = body.additionalProperties.toMutableMap() } /** A list of permissions to add to the role */ - @JsonProperty("add_member_permissions") - fun addMemberPermissions(addMemberPermissions: List) = apply { - this.addMemberPermissions = addMemberPermissions + fun addMemberPermissions(addMemberPermissions: List?) = + addMemberPermissions(JsonField.ofNullable(addMemberPermissions)) + + /** + * Alias for calling [Builder.addMemberPermissions] with + * `addMemberPermissions.orElse(null)`. + */ + fun addMemberPermissions(addMemberPermissions: Optional>) = + addMemberPermissions(addMemberPermissions.getOrNull()) + + /** + * Sets [Builder.addMemberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun addMemberPermissions(addMemberPermissions: JsonField>) = + apply { + this.addMemberPermissions = addMemberPermissions.map { it.toMutableList() } + } + + /** + * Adds a single [AddMemberPermission] to [addMemberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberPermission(addMemberPermission: AddMemberPermission) = apply { + addMemberPermissions = + (addMemberPermissions ?: JsonField.of(mutableListOf())).also { + checkKnown("addMemberPermissions", it).add(addMemberPermission) + } } /** A list of role IDs to add to the role's inheriting-from set */ - @JsonProperty("add_member_roles") - fun addMemberRoles(addMemberRoles: List) = apply { - this.addMemberRoles = addMemberRoles + fun addMemberRoles(addMemberRoles: List?) = + addMemberRoles(JsonField.ofNullable(addMemberRoles)) + + /** Alias for calling [Builder.addMemberRoles] with `addMemberRoles.orElse(null)`. */ + fun addMemberRoles(addMemberRoles: Optional>) = + addMemberRoles(addMemberRoles.getOrNull()) + + /** + * Sets [Builder.addMemberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberRoles] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun addMemberRoles(addMemberRoles: JsonField>) = apply { + this.addMemberRoles = addMemberRoles.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [addMemberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberRole(addMemberRole: String) = apply { + addMemberRoles = + (addMemberRoles ?: JsonField.of(mutableListOf())).also { + checkKnown("addMemberRoles", it).add(addMemberRole) + } } /** Textual description of the role */ - @JsonProperty("description") - fun description(description: String) = apply { this.description = description } + 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 + } /** Name of the role */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 list of permissions to remove from the role */ - @JsonProperty("remove_member_permissions") - fun removeMemberPermissions(removeMemberPermissions: List) = - apply { - this.removeMemberPermissions = removeMemberPermissions - } + fun removeMemberPermissions(removeMemberPermissions: List?) = + removeMemberPermissions(JsonField.ofNullable(removeMemberPermissions)) + + /** + * Alias for calling [Builder.removeMemberPermissions] with + * `removeMemberPermissions.orElse(null)`. + */ + fun removeMemberPermissions( + removeMemberPermissions: Optional> + ) = removeMemberPermissions(removeMemberPermissions.getOrNull()) + + /** + * Sets [Builder.removeMemberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun removeMemberPermissions( + removeMemberPermissions: JsonField> + ) = apply { + this.removeMemberPermissions = removeMemberPermissions.map { it.toMutableList() } + } + + /** + * Adds a single [RemoveMemberPermission] to [removeMemberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberPermission(removeMemberPermission: RemoveMemberPermission) = apply { + removeMemberPermissions = + (removeMemberPermissions ?: JsonField.of(mutableListOf())).also { + checkKnown("removeMemberPermissions", it).add(removeMemberPermission) + } + } /** A list of role IDs to remove from the role's inheriting-from set */ - @JsonProperty("remove_member_roles") - fun removeMemberRoles(removeMemberRoles: List) = apply { - this.removeMemberRoles = removeMemberRoles + fun removeMemberRoles(removeMemberRoles: List?) = + removeMemberRoles(JsonField.ofNullable(removeMemberRoles)) + + /** + * Alias for calling [Builder.removeMemberRoles] with `removeMemberRoles.orElse(null)`. + */ + fun removeMemberRoles(removeMemberRoles: Optional>) = + removeMemberRoles(removeMemberRoles.getOrNull()) + + /** + * Sets [Builder.removeMemberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberRoles] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun removeMemberRoles(removeMemberRoles: JsonField>) = apply { + this.removeMemberRoles = removeMemberRoles.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [removeMemberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberRole(removeMemberRole: String) = apply { + removeMemberRoles = + (removeMemberRoles ?: JsonField.of(mutableListOf())).also { + checkKnown("removeMemberRoles", it).add(removeMemberRole) + } } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): RoleUpdateBody = - RoleUpdateBody( - addMemberPermissions?.toUnmodifiable(), - addMemberRoles?.toUnmodifiable(), + 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. + */ + fun build(): Body = + Body( + (addMemberPermissions ?: JsonMissing.of()).map { it.toImmutable() }, + (addMemberRoles ?: JsonMissing.of()).map { it.toImmutable() }, description, name, - removeMemberPermissions?.toUnmodifiable(), - removeMemberRoles?.toUnmodifiable(), - additionalProperties.toUnmodifiable(), + (removeMemberPermissions ?: JsonMissing.of()).map { it.toImmutable() }, + (removeMemberRoles ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && addMemberPermissions == other.addMemberPermissions && addMemberRoles == other.addMemberRoles && description == other.description && name == other.name && removeMemberPermissions == other.removeMemberPermissions && removeMemberRoles == other.removeMemberRoles && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is RoleUpdateParams && - this.roleId == other.roleId && - this.addMemberPermissions == other.addMemberPermissions && - this.addMemberRoles == other.addMemberRoles && - this.description == other.description && - this.name == other.name && - this.removeMemberPermissions == other.removeMemberPermissions && - this.removeMemberRoles == other.removeMemberRoles && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(addMemberPermissions, addMemberRoles, description, name, removeMemberPermissions, removeMemberRoles, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - roleId, - addMemberPermissions, - addMemberRoles, - description, - name, - removeMemberPermissions, - removeMemberRoles, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "RoleUpdateParams{roleId=$roleId, addMemberPermissions=$addMemberPermissions, addMemberRoles=$addMemberRoles, description=$description, name=$name, removeMemberPermissions=$removeMemberPermissions, removeMemberRoles=$removeMemberRoles, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{addMemberPermissions=$addMemberPermissions, addMemberRoles=$addMemberRoles, description=$description, name=$name, removeMemberPermissions=$removeMemberPermissions, removeMemberRoles=$removeMemberRoles, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RoleUpdateParams]. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [RoleUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var roleId: String? = null - private var addMemberPermissions: MutableList = mutableListOf() - private var addMemberRoles: MutableList = mutableListOf() - private var description: String? = null - private var name: String? = null - private var removeMemberPermissions: MutableList = mutableListOf() - private var removeMemberRoles: MutableList = mutableListOf() - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(roleUpdateParams: RoleUpdateParams) = apply { - this.roleId = roleUpdateParams.roleId - this.addMemberPermissions(roleUpdateParams.addMemberPermissions ?: listOf()) - this.addMemberRoles(roleUpdateParams.addMemberRoles ?: listOf()) - this.description = roleUpdateParams.description - this.name = roleUpdateParams.name - this.removeMemberPermissions(roleUpdateParams.removeMemberPermissions ?: listOf()) - this.removeMemberRoles(roleUpdateParams.removeMemberRoles ?: listOf()) - additionalQueryParams(roleUpdateParams.additionalQueryParams) - additionalHeaders(roleUpdateParams.additionalHeaders) - additionalBodyProperties(roleUpdateParams.additionalBodyProperties) + roleId = roleUpdateParams.roleId + body = roleUpdateParams.body.toBuilder() + additionalHeaders = roleUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = roleUpdateParams.additionalQueryParams.toBuilder() } /** Role id */ fun roleId(roleId: String) = apply { this.roleId = roleId } /** A list of permissions to add to the role */ - fun addMemberPermissions(addMemberPermissions: List) = apply { - this.addMemberPermissions.clear() - this.addMemberPermissions.addAll(addMemberPermissions) + fun addMemberPermissions(addMemberPermissions: List?) = apply { + body.addMemberPermissions(addMemberPermissions) } - /** A list of permissions to add to the role */ + /** + * Alias for calling [Builder.addMemberPermissions] with + * `addMemberPermissions.orElse(null)`. + */ + fun addMemberPermissions(addMemberPermissions: Optional>) = + addMemberPermissions(addMemberPermissions.getOrNull()) + + /** + * Sets [Builder.addMemberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun addMemberPermissions(addMemberPermissions: JsonField>) = + apply { + body.addMemberPermissions(addMemberPermissions) + } + + /** + * Adds a single [AddMemberPermission] to [addMemberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addAddMemberPermission(addMemberPermission: AddMemberPermission) = apply { - this.addMemberPermissions.add(addMemberPermission) + body.addAddMemberPermission(addMemberPermission) } /** A list of role IDs to add to the role's inheriting-from set */ - fun addMemberRoles(addMemberRoles: List) = apply { - this.addMemberRoles.clear() - this.addMemberRoles.addAll(addMemberRoles) + fun addMemberRoles(addMemberRoles: List?) = apply { + body.addMemberRoles(addMemberRoles) } - /** A list of role IDs to add to the role's inheriting-from set */ - fun addAddMemberRole(addMemberRole: String) = apply { - this.addMemberRoles.add(addMemberRole) + /** Alias for calling [Builder.addMemberRoles] with `addMemberRoles.orElse(null)`. */ + fun addMemberRoles(addMemberRoles: Optional>) = + addMemberRoles(addMemberRoles.getOrNull()) + + /** + * Sets [Builder.addMemberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.addMemberRoles] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun addMemberRoles(addMemberRoles: JsonField>) = apply { + body.addMemberRoles(addMemberRoles) } + /** + * Adds a single [String] to [addMemberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAddMemberRole(addMemberRole: String) = apply { body.addAddMemberRole(addMemberRole) } + /** Textual description of the role */ - fun description(description: String) = apply { this.description = description } + 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) } /** Name of the role */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } - /** A list of permissions to remove from the role */ - fun removeMemberPermissions(removeMemberPermissions: List) = apply { - this.removeMemberPermissions.clear() - this.removeMemberPermissions.addAll(removeMemberPermissions) - } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 list of permissions to remove from the role */ + fun removeMemberPermissions(removeMemberPermissions: List?) = + apply { + body.removeMemberPermissions(removeMemberPermissions) + } + + /** + * Alias for calling [Builder.removeMemberPermissions] with + * `removeMemberPermissions.orElse(null)`. + */ + fun removeMemberPermissions( + removeMemberPermissions: Optional> + ) = removeMemberPermissions(removeMemberPermissions.getOrNull()) + + /** + * Sets [Builder.removeMemberPermissions] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberPermissions] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun removeMemberPermissions( + removeMemberPermissions: JsonField> + ) = apply { body.removeMemberPermissions(removeMemberPermissions) } + + /** + * Adds a single [RemoveMemberPermission] to [removeMemberPermissions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ fun addRemoveMemberPermission(removeMemberPermission: RemoveMemberPermission) = apply { - this.removeMemberPermissions.add(removeMemberPermission) + body.addRemoveMemberPermission(removeMemberPermission) } /** A list of role IDs to remove from the role's inheriting-from set */ - fun removeMemberRoles(removeMemberRoles: List) = apply { - this.removeMemberRoles.clear() - this.removeMemberRoles.addAll(removeMemberRoles) + fun removeMemberRoles(removeMemberRoles: List?) = apply { + body.removeMemberRoles(removeMemberRoles) } - /** A list of role IDs to remove from the role's inheriting-from set */ - fun addRemoveMemberRole(removeMemberRole: String) = apply { - this.removeMemberRoles.add(removeMemberRole) + /** Alias for calling [Builder.removeMemberRoles] with `removeMemberRoles.orElse(null)`. */ + fun removeMemberRoles(removeMemberRoles: Optional>) = + removeMemberRoles(removeMemberRoles.getOrNull()) + + /** + * Sets [Builder.removeMemberRoles] to an arbitrary JSON value. + * + * You should usually call [Builder.removeMemberRoles] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun removeMemberRoles(removeMemberRoles: JsonField>) = apply { + body.removeMemberRoles(removeMemberRoles) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** + * Adds a single [String] to [removeMemberRoles]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRemoveMemberRole(removeMemberRole: String) = apply { + body.addRemoveMemberRole(removeMemberRole) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + 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.additionalBodyProperties.putAll(additionalBodyProperties) + 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 [RoleUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .roleId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RoleUpdateParams = RoleUpdateParams( - checkNotNull(roleId) { "`roleId` is required but was not set" }, - if (addMemberPermissions.size == 0) null else addMemberPermissions.toUnmodifiable(), - if (addMemberRoles.size == 0) null else addMemberRoles.toUnmodifiable(), - description, - name, - if (removeMemberPermissions.size == 0) null - else removeMemberPermissions.toUnmodifiable(), - if (removeMemberRoles.size == 0) null else removeMemberRoles.toUnmodifiable(), - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), + checkRequired("roleId", roleId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } - @JsonDeserialize(builder = AddMemberPermission.Builder::class) @NoAutoDetect class AddMemberPermission + @JsonCreator private constructor( - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val additionalProperties: Map, + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * Each permission permits a certain type of operation on an object in the system * * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * + * @throws BraintrustInvalidDataException 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 permission(): Permission = permission.getRequired("permission") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("permission") fun permission(): Permission? = permission + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission - /** The object type that the ACL applies to */ + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): AddMemberPermission = apply { + if (validated) { + return@apply } - return other is AddMemberPermission && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.additionalProperties == other.additionalProperties + permission() + restrictObjectType() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - permission, - restrictObjectType, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "AddMemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [AddMemberPermission]. + * + * The following fields are required: + * ```java + * .permission() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [AddMemberPermission]. */ + class Builder internal constructor() { - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null + private var permission: JsonField? = null + private var restrictObjectType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(addMemberPermission: AddMemberPermission) = apply { - this.permission = addMemberPermission.permission - this.restrictObjectType = addMemberPermission.restrictObjectType - additionalProperties(addMemberPermission.additionalProperties) + permission = addMemberPermission.permission + restrictObjectType = addMemberPermission.restrictObjectType + additionalProperties = addMemberPermission.additionalProperties.toMutableMap() } /** @@ -511,313 +991,193 @@ constructor( * Permissions can be assigned to to objects on an individual basis, or grouped into * roles */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun permission(permission: Permission) = permission(JsonField.of(permission)) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [AddMemberPermission]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .permission() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): AddMemberPermission = AddMemberPermission( - checkNotNull(permission) { "`permission` is required but was not set" }, + checkRequired("permission", permission), restrictObjectType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + return /* spotless:off */ other is AddMemberPermission && permission == other.permission && restrictObjectType == other.restrictObjectType && additionalProperties == other.additionalProperties /* spotless:on */ } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(permission, restrictObjectType, additionalProperties) } + /* spotless:on */ - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) + override fun hashCode(): Int = hashCode - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } - - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "AddMemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = RemoveMemberPermission.Builder::class) @NoAutoDetect class RemoveMemberPermission + @JsonCreator private constructor( - private val permission: Permission?, - private val restrictObjectType: RestrictObjectType?, - private val additionalProperties: Map, + @JsonProperty("permission") + @ExcludeMissing + private val permission: JsonField = JsonMissing.of(), + @JsonProperty("restrict_object_type") + @ExcludeMissing + private val restrictObjectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - /** * Each permission permits a certain type of operation on an object in the system * * Permissions can be assigned to to objects on an individual basis, or grouped into roles + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). */ - @JsonProperty("permission") fun permission(): Permission? = permission + fun permission(): Permission = permission.getRequired("permission") - /** The object type that the ACL applies to */ + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun restrictObjectType(): Optional = + Optional.ofNullable(restrictObjectType.getNullable("restrict_object_type")) + + /** + * Returns the raw JSON value of [permission]. + * + * Unlike [permission], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("permission") + @ExcludeMissing + fun _permission(): JsonField = permission + + /** + * Returns the raw JSON value of [restrictObjectType]. + * + * Unlike [restrictObjectType], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("restrict_object_type") - fun restrictObjectType(): RestrictObjectType? = restrictObjectType + @ExcludeMissing + fun _restrictObjectType(): JsonField = restrictObjectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): RemoveMemberPermission = apply { + if (validated) { + return@apply } - return other is RemoveMemberPermission && - this.permission == other.permission && - this.restrictObjectType == other.restrictObjectType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - permission, - restrictObjectType, - additionalProperties, - ) - } - return hashCode + permission() + restrictObjectType() + validated = true } - override fun toString() = - "RemoveMemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [RemoveMemberPermission]. + * + * The following fields are required: + * ```java + * .permission() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [RemoveMemberPermission]. */ + class Builder internal constructor() { - private var permission: Permission? = null - private var restrictObjectType: RestrictObjectType? = null + private var permission: JsonField? = null + private var restrictObjectType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(removeMemberPermission: RemoveMemberPermission) = apply { - this.permission = removeMemberPermission.permission - this.restrictObjectType = removeMemberPermission.restrictObjectType - additionalProperties(removeMemberPermission.additionalProperties) + permission = removeMemberPermission.permission + restrictObjectType = removeMemberPermission.restrictObjectType + additionalProperties = removeMemberPermission.additionalProperties.toMutableMap() } /** @@ -826,240 +1186,108 @@ constructor( * Permissions can be assigned to to objects on an individual basis, or grouped into * roles */ - @JsonProperty("permission") - fun permission(permission: Permission) = apply { this.permission = permission } + fun permission(permission: Permission) = permission(JsonField.of(permission)) + + /** + * Sets [Builder.permission] to an arbitrary JSON value. + * + * You should usually call [Builder.permission] with a well-typed [Permission] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun permission(permission: JsonField) = apply { + this.permission = permission + } /** The object type that the ACL applies to */ - @JsonProperty("restrict_object_type") - fun restrictObjectType(restrictObjectType: RestrictObjectType) = apply { + fun restrictObjectType(restrictObjectType: AclObjectType?) = + restrictObjectType(JsonField.ofNullable(restrictObjectType)) + + /** + * Alias for calling [Builder.restrictObjectType] with + * `restrictObjectType.orElse(null)`. + */ + fun restrictObjectType(restrictObjectType: Optional) = + restrictObjectType(restrictObjectType.getOrNull()) + + /** + * Sets [Builder.restrictObjectType] to an arbitrary JSON value. + * + * You should usually call [Builder.restrictObjectType] with a well-typed + * [AclObjectType] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun restrictObjectType(restrictObjectType: JsonField) = apply { this.restrictObjectType = restrictObjectType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [RemoveMemberPermission]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .permission() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): RemoveMemberPermission = RemoveMemberPermission( - checkNotNull(permission) { "`permission` is required but was not set" }, + checkRequired("permission", permission), restrictObjectType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - class Permission - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Permission && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val CREATE = Permission(JsonField.of("create")) - - @JvmField val READ = Permission(JsonField.of("read")) - - @JvmField val UPDATE = Permission(JsonField.of("update")) - - @JvmField val DELETE = Permission(JsonField.of("delete")) - - @JvmField val CREATE_ACLS = Permission(JsonField.of("create_acls")) - - @JvmField val READ_ACLS = Permission(JsonField.of("read_acls")) - - @JvmField val UPDATE_ACLS = Permission(JsonField.of("update_acls")) - - @JvmField val DELETE_ACLS = Permission(JsonField.of("delete_acls")) - - @JvmStatic fun of(value: String) = Permission(JsonField.of(value)) - } - - enum class Known { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - } - - enum class Value { - CREATE, - READ, - UPDATE, - DELETE, - CREATE_ACLS, - READ_ACLS, - UPDATE_ACLS, - DELETE_ACLS, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - CREATE -> Value.CREATE - READ -> Value.READ - UPDATE -> Value.UPDATE - DELETE -> Value.DELETE - CREATE_ACLS -> Value.CREATE_ACLS - READ_ACLS -> Value.READ_ACLS - UPDATE_ACLS -> Value.UPDATE_ACLS - DELETE_ACLS -> Value.DELETE_ACLS - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - CREATE -> Known.CREATE - READ -> Known.READ - UPDATE -> Known.UPDATE - DELETE -> Known.DELETE - CREATE_ACLS -> Known.CREATE_ACLS - READ_ACLS -> Known.READ_ACLS - UPDATE_ACLS -> Known.UPDATE_ACLS - DELETE_ACLS -> Known.DELETE_ACLS - else -> throw BraintrustInvalidDataException("Unknown Permission: $value") - } - - fun asString(): String = _value().asStringOrThrow() + return /* spotless:off */ other is RemoveMemberPermission && permission == other.permission && restrictObjectType == other.restrictObjectType && additionalProperties == other.additionalProperties /* spotless:on */ } - class RestrictObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is RestrictObjectType && this.value == other.value - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(permission, restrictObjectType, additionalProperties) } + /* spotless:on */ - override fun hashCode() = value.hashCode() + override fun hashCode(): Int = hashCode - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = RestrictObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = RestrictObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = RestrictObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = RestrictObjectType(JsonField.of("dataset")) - - @JvmField val PROMPT = RestrictObjectType(JsonField.of("prompt")) - - @JvmField val PROMPT_SESSION = RestrictObjectType(JsonField.of("prompt_session")) - - @JvmField val GROUP = RestrictObjectType(JsonField.of("group")) - - @JvmField val ROLE = RestrictObjectType(JsonField.of("role")) - - @JvmField val ORG_MEMBER = RestrictObjectType(JsonField.of("org_member")) - - @JvmField val PROJECT_LOG = RestrictObjectType(JsonField.of("project_log")) - - @JvmField val ORG_PROJECT = RestrictObjectType(JsonField.of("org_project")) - - @JvmStatic fun of(value: String) = RestrictObjectType(JsonField.of(value)) - } - - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + override fun toString() = + "RemoveMemberPermission{permission=$permission, restrictObjectType=$restrictObjectType, additionalProperties=$additionalProperties}" + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is RoleUpdateParams && roleId == other.roleId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> - throw BraintrustInvalidDataException("Unknown RestrictObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(roleId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } - } + override fun toString() = + "RoleUpdateParams{roleId=$roleId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ScoreSummary.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ScoreSummary.kt index 3eed5fbd..2d7c5189 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ScoreSummary.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ScoreSummary.kt @@ -7,196 +7,284 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional /** Summary of a score's performance */ -@JsonDeserialize(builder = ScoreSummary.Builder::class) @NoAutoDetect class ScoreSummary +@JsonCreator private constructor( - private val name: JsonField, - private val score: JsonField, - private val diff: JsonField, - private val improvements: JsonField, - private val regressions: JsonField, - private val additionalProperties: Map, + @JsonProperty("improvements") + @ExcludeMissing + private val improvements: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("regressions") + @ExcludeMissing + private val regressions: JsonField = JsonMissing.of(), + @JsonProperty("score") @ExcludeMissing private val score: JsonField = JsonMissing.of(), + @JsonProperty("diff") @ExcludeMissing private val diff: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 + /** + * Number of improvements in the score + * + * @throws BraintrustInvalidDataException 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 improvements(): Long = improvements.getRequired("improvements") - /** Name of the score */ + /** + * Name of the score + * + * @throws BraintrustInvalidDataException 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") - /** Average score across all examples */ - fun score(): Double = score.getRequired("score") - - /** Difference in score between the current and comparison experiment */ - fun diff(): Optional = Optional.ofNullable(diff.getNullable("diff")) - - /** Number of improvements in the score */ - fun improvements(): Long = improvements.getRequired("improvements") - - /** Number of regressions in the score */ + /** + * Number of regressions in the score + * + * @throws BraintrustInvalidDataException 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 regressions(): Long = regressions.getRequired("regressions") - /** Name of the score */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Average score across all examples */ - @JsonProperty("score") @ExcludeMissing fun _score() = score - - /** Difference in score between the current and comparison experiment */ - @JsonProperty("diff") @ExcludeMissing fun _diff() = diff + /** + * Average score across all examples + * + * @throws BraintrustInvalidDataException 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 score(): Double = score.getRequired("score") - /** Number of improvements in the score */ - @JsonProperty("improvements") @ExcludeMissing fun _improvements() = improvements + /** + * Difference in score between the current and comparison experiment + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun diff(): Optional = Optional.ofNullable(diff.getNullable("diff")) - /** Number of regressions in the score */ - @JsonProperty("regressions") @ExcludeMissing fun _regressions() = regressions + /** + * Returns the raw JSON value of [improvements]. + * + * Unlike [improvements], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("improvements") + @ExcludeMissing + fun _improvements(): JsonField = improvements + + /** + * 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 [regressions]. + * + * Unlike [regressions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("regressions") @ExcludeMissing fun _regressions(): JsonField = regressions + + /** + * Returns the raw JSON value of [score]. + * + * Unlike [score], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("score") @ExcludeMissing fun _score(): JsonField = score + + /** + * Returns the raw JSON value of [diff]. + * + * Unlike [diff], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("diff") @ExcludeMissing fun _diff(): JsonField = diff @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ScoreSummary = apply { - if (!validated) { - name() - score() - diff() - improvements() - regressions() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ScoreSummary = apply { + if (validated) { + return@apply } - return other is ScoreSummary && - this.name == other.name && - this.score == other.score && - this.diff == other.diff && - this.improvements == other.improvements && - this.regressions == other.regressions && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - score, - diff, - improvements, - regressions, - additionalProperties, - ) - } - return hashCode + improvements() + name() + regressions() + score() + diff() + validated = true } - override fun toString() = - "ScoreSummary{name=$name, score=$score, diff=$diff, improvements=$improvements, regressions=$regressions, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ScoreSummary]. + * + * The following fields are required: + * ```java + * .improvements() + * .name() + * .regressions() + * .score() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ScoreSummary]. */ + class Builder internal constructor() { - private var name: JsonField = JsonMissing.of() - private var score: JsonField = JsonMissing.of() + private var improvements: JsonField? = null + private var name: JsonField? = null + private var regressions: JsonField? = null + private var score: JsonField? = null private var diff: JsonField = JsonMissing.of() - private var improvements: JsonField = JsonMissing.of() - private var regressions: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scoreSummary: ScoreSummary) = apply { - this.name = scoreSummary.name - this.score = scoreSummary.score - this.diff = scoreSummary.diff - this.improvements = scoreSummary.improvements - this.regressions = scoreSummary.regressions - additionalProperties(scoreSummary.additionalProperties) + improvements = scoreSummary.improvements + name = scoreSummary.name + regressions = scoreSummary.regressions + score = scoreSummary.score + diff = scoreSummary.diff + additionalProperties = scoreSummary.additionalProperties.toMutableMap() } + /** Number of improvements in the score */ + fun improvements(improvements: Long) = improvements(JsonField.of(improvements)) + + /** + * Sets [Builder.improvements] to an arbitrary JSON value. + * + * You should usually call [Builder.improvements] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun improvements(improvements: JsonField) = apply { this.improvements = improvements } + /** Name of the score */ fun name(name: String) = name(JsonField.of(name)) - /** Name of the score */ - @JsonProperty("name") - @ExcludeMissing + /** + * 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 } + /** Number of regressions in the score */ + fun regressions(regressions: Long) = regressions(JsonField.of(regressions)) + + /** + * Sets [Builder.regressions] to an arbitrary JSON value. + * + * You should usually call [Builder.regressions] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun regressions(regressions: JsonField) = apply { this.regressions = regressions } + /** Average score across all examples */ fun score(score: Double) = score(JsonField.of(score)) - /** Average score across all examples */ - @JsonProperty("score") - @ExcludeMissing + /** + * Sets [Builder.score] to an arbitrary JSON value. + * + * You should usually call [Builder.score] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun score(score: JsonField) = apply { this.score = score } /** Difference in score between the current and comparison experiment */ fun diff(diff: Double) = diff(JsonField.of(diff)) - /** Difference in score between the current and comparison experiment */ - @JsonProperty("diff") - @ExcludeMissing + /** + * Sets [Builder.diff] to an arbitrary JSON value. + * + * You should usually call [Builder.diff] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun diff(diff: JsonField) = apply { this.diff = diff } - /** Number of improvements in the score */ - fun improvements(improvements: Long) = improvements(JsonField.of(improvements)) - - /** Number of improvements in the score */ - @JsonProperty("improvements") - @ExcludeMissing - fun improvements(improvements: JsonField) = apply { this.improvements = improvements } - - /** Number of regressions in the score */ - fun regressions(regressions: Long) = regressions(JsonField.of(regressions)) - - /** Number of regressions in the score */ - @JsonProperty("regressions") - @ExcludeMissing - fun regressions(regressions: JsonField) = apply { this.regressions = regressions } - fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ScoreSummary]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .improvements() + * .name() + * .regressions() + * .score() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): ScoreSummary = ScoreSummary( - name, - score, + checkRequired("improvements", improvements), + checkRequired("name", name), + checkRequired("regressions", regressions), + checkRequired("score", score), diff, - improvements, - regressions, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ScoreSummary && improvements == other.improvements && name == other.name && regressions == other.regressions && score == other.score && diff == other.diff && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(improvements, name, regressions, score, diff, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ScoreSummary{improvements=$improvements, name=$name, regressions=$regressions, score=$score, diff=$diff, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Scorer.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Scorer.kt deleted file mode 100644 index 11d30316..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Scorer.kt +++ /dev/null @@ -1,183 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.util.Objects - -@JsonDeserialize(builder = Scorer.Builder::class) -@NoAutoDetect -class Scorer -private constructor( - private val type: JsonField, - private val index: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") - - fun index(): Long = index.getRequired("index") - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("index") @ExcludeMissing fun _index() = index - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Scorer = apply { - if (!validated) { - type() - index() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Scorer && - this.type == other.type && - this.index == other.index && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - index, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Scorer{type=$type, index=$index, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var type: JsonField = JsonMissing.of() - private var index: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(scorer: Scorer) = apply { - this.type = scorer.type - this.index = scorer.index - additionalProperties(scorer.additionalProperties) - } - - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun index(index: Long) = index(JsonField.of(index)) - - @JsonProperty("index") - @ExcludeMissing - fun index(index: JsonField) = apply { this.index = index } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Scorer = - Scorer( - type, - index, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val SCORER = Type(JsonField.of("scorer")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - SCORER, - } - - enum class Value { - SCORER, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - SCORER -> Value.SCORER - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - SCORER -> Known.SCORER - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanAttributes.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanAttributes.kt new file mode 100644 index 00000000..68f8d827 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanAttributes.kt @@ -0,0 +1,170 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Human-identifying attributes of the span, such as name, type, etc. */ +@NoAutoDetect +class SpanAttributes +@JsonCreator +private constructor( + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing private val type: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * Name of the span, for display purposes only + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Type of the span, for display purposes only + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun type(): Optional = Optional.ofNullable(type.getNullable("type")) + + /** + * 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 [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): SpanAttributes = apply { + if (validated) { + return@apply + } + + name() + type() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [SpanAttributes]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanAttributes]. */ + class Builder internal constructor() { + + private var name: JsonField = JsonMissing.of() + private var type: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(spanAttributes: SpanAttributes) = apply { + name = spanAttributes.name + type = spanAttributes.type + additionalProperties = spanAttributes.additionalProperties.toMutableMap() + } + + /** Name of the span, for display purposes only */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } + + /** Type of the span, for display purposes only */ + fun type(type: SpanType?) = type(JsonField.ofNullable(type)) + + /** Alias for calling [Builder.type] with `type.orElse(null)`. */ + fun type(type: Optional) = type(type.getOrNull()) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [SpanType] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [SpanAttributes]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SpanAttributes = SpanAttributes(name, type, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanAttributes && name == other.name && type == other.type && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, type, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SpanAttributes{name=$name, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIFrame.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIFrame.kt new file mode 100644 index 00000000..bd4d2359 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIFrame.kt @@ -0,0 +1,457 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.time.OffsetDateTime +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +@NoAutoDetect +class SpanIFrame +@JsonCreator +private constructor( + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing private val url: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("post_message") + @ExcludeMissing + private val postMessage: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), +) { + + /** + * Unique identifier for the span iframe + * + * @throws BraintrustInvalidDataException 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") + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the span iframe belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException 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 url(): String = url.getRequired("url") + + /** + * Date of span iframe creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun created(): Optional = Optional.ofNullable(created.getNullable("created")) + + /** + * Date of span iframe deletion, or null if the span iframe is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun deletedAt(): Optional = + Optional.ofNullable(deletedAt.getNullable("deleted_at")) + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when you + * want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun postMessage(): Optional = + Optional.ofNullable(postMessage.getNullable("post_message")) + + /** + * Identifies the user who created the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * 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 [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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * 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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("post_message") + @ExcludeMissing + fun _postMessage(): JsonField = postMessage + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): SpanIFrame = apply { + if (validated) { + return@apply + } + + id() + name() + projectId() + url() + created() + deletedAt() + description() + postMessage() + userId() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIFrame]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIFrame]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var name: JsonField? = null + private var projectId: JsonField? = null + private var url: JsonField? = null + private var created: JsonField = JsonMissing.of() + private var deletedAt: JsonField = JsonMissing.of() + private var description: JsonField = JsonMissing.of() + private var postMessage: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(spanIFrame: SpanIFrame) = apply { + id = spanIFrame.id + name = spanIFrame.name + projectId = spanIFrame.projectId + url = spanIFrame.url + created = spanIFrame.created + deletedAt = spanIFrame.deletedAt + description = spanIFrame.description + postMessage = spanIFrame.postMessage + userId = spanIFrame.userId + additionalProperties = spanIFrame.additionalProperties.toMutableMap() + } + + /** Unique identifier for the span iframe */ + 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 } + + /** Name of the span iframe */ + 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 } + + /** Unique identifier for the project that the span iframe belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun url(url: JsonField) = apply { this.url = url } + + /** Date of span iframe creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** Date of span iframe deletion, or null if the span iframe is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + + /** Textual description of the span iframe */ + 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 to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = postMessage(JsonField.ofNullable(postMessage)) + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun postMessage(postMessage: JsonField) = apply { this.postMessage = postMessage } + + /** Identifies the user who created the span iframe */ + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } + + 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 [SpanIFrame]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .projectId() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIFrame = + SpanIFrame( + checkRequired("id", id), + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("url", url), + created, + deletedAt, + description, + postMessage, + userId, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIFrame && id == other.id && name == other.name && projectId == other.projectId && url == other.url && created == other.created && deletedAt == other.deletedAt && description == other.description && postMessage == other.postMessage && userId == other.userId && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, projectId, url, created, deletedAt, description, postMessage, userId, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SpanIFrame{id=$id, name=$name, projectId=$projectId, url=$url, created=$created, deletedAt=$deletedAt, description=$description, postMessage=$postMessage, userId=$userId, additionalProperties=$additionalProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeCreateParams.kt new file mode 100644 index 00000000..6883efec --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeCreateParams.kt @@ -0,0 +1,682 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Create a new span_iframe. If there is an existing span_iframe with the same name as the one + * specified in the request, will return the existing span_iframe unmodified + */ +class SpanIframeCreateParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the span iframe belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException 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 url(): String = body.url() + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when you + * want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun postMessage(): Optional = body.postMessage() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _url(): JsonField = body._url() + + /** + * 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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _postMessage(): JsonField = body._postMessage() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + @NoAutoDetect + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing private val url: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("post_message") + @ExcludeMissing + private val postMessage: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the span iframe belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException 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 url(): String = url.getRequired("url") + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun postMessage(): Optional = + Optional.ofNullable(postMessage.getNullable("post_message")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + /** + * 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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("post_message") + @ExcludeMissing + fun _postMessage(): JsonField = postMessage + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + name() + projectId() + url() + description() + postMessage() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var projectId: JsonField? = null + private var url: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var postMessage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + url = body.url + description = body.description + postMessage = body.postMessage + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Name of the span iframe */ + 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 } + + /** Unique identifier for the project that the span iframe belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + /** Textual description of the span iframe */ + 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 to post messages to the iframe containing the span's data. This is useful + * when you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = postMessage(JsonField.ofNullable(postMessage)) + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postMessage(postMessage: JsonField) = apply { + this.postMessage = postMessage + } + + 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() + * .projectId() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("url", url), + description, + postMessage, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && url == other.url && description == other.description && postMessage == other.postMessage && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, url, description, postMessage, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{name=$name, projectId=$projectId, url=$url, description=$description, postMessage=$postMessage, additionalProperties=$additionalProperties}" + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeCreateParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + 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(spanIframeCreateParams: SpanIframeCreateParams) = apply { + body = spanIframeCreateParams.body.toBuilder() + additionalHeaders = spanIframeCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeCreateParams.additionalQueryParams.toBuilder() + } + + /** Name of the span iframe */ + 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) } + + /** Unique identifier for the project that the span iframe belongs under */ + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String) = apply { body.url(url) } + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun url(url: JsonField) = apply { body.url(url) } + + /** Textual description of the span iframe */ + 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 to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = apply { body.postMessage(postMessage) } + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun postMessage(postMessage: JsonField) = apply { body.postMessage(postMessage) } + + 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 [SpanIframeCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIframeCreateParams = + SpanIframeCreateParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "SpanIframeCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParams.kt new file mode 100644 index 00000000..da0b2c4a --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParams.kt @@ -0,0 +1,237 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.toImmutable +import java.util.Objects +import java.util.Optional + +/** Delete a span_iframe object by its id */ +class SpanIframeDeleteParams +private constructor( + private val spanIframeId: String, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + /** SpanIframe id */ + fun spanIframeId(): String = spanIframeId + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun _additionalBodyProperties(): Map = additionalBodyProperties + + @JvmSynthetic + internal fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + fun getPathParam(index: Int): String { + return when (index) { + 0 -> spanIframeId + else -> "" + } + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeDeleteParams]. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeDeleteParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + private var spanIframeId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(spanIframeDeleteParams: SpanIframeDeleteParams) = apply { + spanIframeId = spanIframeDeleteParams.spanIframeId + additionalHeaders = spanIframeDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + spanIframeDeleteParams.additionalBodyProperties.toMutableMap() + } + + /** SpanIframe id */ + fun spanIframeId(spanIframeId: String) = apply { this.spanIframeId = spanIframeId } + + 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) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [SpanIframeDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIframeDeleteParams = + SpanIframeDeleteParams( + checkRequired("spanIframeId", spanIframeId), + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeDeleteParams && spanIframeId == other.spanIframeId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams && additionalBodyProperties == other.additionalBodyProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanIframeId, additionalHeaders, additionalQueryParams, additionalBodyProperties) /* spotless:on */ + + override fun toString() = + "SpanIframeDeleteParams{spanIframeId=$spanIframeId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPage.kt new file mode 100644 index 00000000..0018bcf6 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPage.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.services.blocking.SpanIframeService +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 java.util.Objects +import java.util.Optional +import java.util.stream.Stream +import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull + +/** + * List out all span_iframes. The span_iframes are sorted by creation date, with the most + * recently-created span_iframes coming first + */ +class SpanIframeListPage +private constructor( + private val spanIframesService: SpanIframeService, + private val params: SpanIframeListParams, + private val response: Response, +) { + + fun response(): Response = response + + fun objects(): List = response().objects() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeListPage && spanIframesService == other.spanIframesService && params == other.params && response == other.response /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanIframesService, params, response) /* spotless:on */ + + override fun toString() = + "SpanIframeListPage{spanIframesService=$spanIframesService, params=$params, response=$response}" + + fun hasNextPage(): Boolean { + return !objects().isEmpty() + } + + fun getNextPageParams(): Optional { + if (!hasNextPage()) { + return Optional.empty() + } + + return if (params.endingBefore().isPresent) { + Optional.of( + SpanIframeListParams.builder() + .from(params) + .endingBefore(objects().first().id()) + .build() + ) + } else { + Optional.of( + SpanIframeListParams.builder() + .from(params) + .startingAfter(objects().last().id()) + .build() + ) + } + } + + fun getNextPage(): Optional { + return getNextPageParams().map { spanIframesService.list(it) } + } + + fun autoPager(): AutoPager = AutoPager(this) + + companion object { + + @JvmStatic + fun of( + spanIframesService: SpanIframeService, + params: SpanIframeListParams, + response: Response, + ) = SpanIframeListPage(spanIframesService, params, response) + } + + @NoAutoDetect + class Response + @JsonCreator + constructor( + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + fun objects(): List = objects.getNullable("objects") ?: listOf() + + @JsonProperty("objects") + fun _objects(): Optional>> = Optional.ofNullable(objects) + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Response = apply { + if (validated) { + return@apply + } + + objects().map { it.validate() } + validated = true + } + + fun toBuilder() = Builder().from(this) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ + + override fun toString() = + "Response{objects=$objects, additionalProperties=$additionalProperties}" + + companion object { + + /** Returns a mutable builder for constructing an instance of [SpanIframeListPage]. */ + @JvmStatic fun builder() = Builder() + } + + class Builder { + + private var objects: JsonField> = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(page: Response) = apply { + this.objects = page.objects + this.additionalProperties.putAll(page.additionalProperties) + } + + fun objects(objects: List) = objects(JsonField.of(objects)) + + fun objects(objects: JsonField>) = apply { this.objects = objects } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + this.additionalProperties.put(key, value) + } + + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) + } + } + + class AutoPager(private val firstPage: SpanIframeListPage) : Iterable { + + override fun iterator(): Iterator = iterator { + var page = firstPage + var index = 0 + while (true) { + while (index < page.objects().size) { + yield(page.objects()[index++]) + } + page = page.getNextPage().getOrNull() ?: break + index = 0 + } + } + + fun stream(): Stream { + return StreamSupport.stream(spliterator(), false) + } + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPageAsync.kt new file mode 100644 index 00000000..b7d9bd94 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListPageAsync.kt @@ -0,0 +1,201 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.services.async.SpanIframeServiceAsync +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 java.util.Objects +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import java.util.function.Predicate + +/** + * List out all span_iframes. The span_iframes are sorted by creation date, with the most + * recently-created span_iframes coming first + */ +class SpanIframeListPageAsync +private constructor( + private val spanIframesService: SpanIframeServiceAsync, + private val params: SpanIframeListParams, + private val response: Response, +) { + + fun response(): Response = response + + fun objects(): List = response().objects() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeListPageAsync && spanIframesService == other.spanIframesService && params == other.params && response == other.response /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanIframesService, params, response) /* spotless:on */ + + override fun toString() = + "SpanIframeListPageAsync{spanIframesService=$spanIframesService, params=$params, response=$response}" + + fun hasNextPage(): Boolean { + return !objects().isEmpty() + } + + fun getNextPageParams(): Optional { + if (!hasNextPage()) { + return Optional.empty() + } + + return if (params.endingBefore().isPresent) { + Optional.of( + SpanIframeListParams.builder() + .from(params) + .endingBefore(objects().first().id()) + .build() + ) + } else { + Optional.of( + SpanIframeListParams.builder() + .from(params) + .startingAfter(objects().last().id()) + .build() + ) + } + } + + fun getNextPage(): CompletableFuture> { + return getNextPageParams() + .map { spanIframesService.list(it).thenApply { Optional.of(it) } } + .orElseGet { CompletableFuture.completedFuture(Optional.empty()) } + } + + fun autoPager(): AutoPager = AutoPager(this) + + companion object { + + @JvmStatic + fun of( + spanIframesService: SpanIframeServiceAsync, + params: SpanIframeListParams, + response: Response, + ) = SpanIframeListPageAsync(spanIframesService, params, response) + } + + @NoAutoDetect + class Response + @JsonCreator + constructor( + @JsonProperty("objects") + private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + fun objects(): List = objects.getNullable("objects") ?: listOf() + + @JsonProperty("objects") + fun _objects(): Optional>> = Optional.ofNullable(objects) + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Response = apply { + if (validated) { + return@apply + } + + objects().map { it.validate() } + validated = true + } + + fun toBuilder() = Builder().from(this) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ + + override fun toString() = + "Response{objects=$objects, additionalProperties=$additionalProperties}" + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeListPageAsync]. + */ + @JvmStatic fun builder() = Builder() + } + + class Builder { + + private var objects: JsonField> = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(page: Response) = apply { + this.objects = page.objects + this.additionalProperties.putAll(page.additionalProperties) + } + + fun objects(objects: List) = objects(JsonField.of(objects)) + + fun objects(objects: JsonField>) = apply { this.objects = objects } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + this.additionalProperties.put(key, value) + } + + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) + } + } + + class AutoPager(private val firstPage: SpanIframeListPageAsync) { + + fun forEach(action: Predicate, executor: Executor): CompletableFuture { + fun CompletableFuture>.forEach( + action: (SpanIFrame) -> Boolean, + executor: Executor, + ): CompletableFuture = + thenComposeAsync( + { page -> + page + .filter { it.objects().all(action) } + .map { it.getNextPage().forEach(action, executor) } + .orElseGet { CompletableFuture.completedFuture(null) } + }, + executor, + ) + return CompletableFuture.completedFuture(Optional.of(firstPage)) + .forEach(action::test, executor) + } + + fun toList(executor: Executor): CompletableFuture> { + val values = mutableListOf() + return forEach(values::add, executor).thenApply { values } + } + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListParams.kt new file mode 100644 index 00000000..fdfa8f86 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeListParams.kt @@ -0,0 +1,446 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.BaseDeserializer +import com.braintrustdata.api.core.BaseSerializer +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.getOrThrow +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * List out all span_iframes. The span_iframes are sorted by creation date, with the most + * recently-created span_iframes coming first + */ +class SpanIframeListParams +private constructor( + private val endingBefore: String?, + private val ids: Ids?, + private val limit: Long?, + private val orgName: String?, + private val spanIframeName: String?, + private val startingAfter: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ + fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ + fun ids(): Optional = Optional.ofNullable(ids) + + /** Limit the number of objects to return */ + fun limit(): Optional = Optional.ofNullable(limit) + + /** Filter search results to within a particular organization */ + fun orgName(): Optional = Optional.ofNullable(orgName) + + /** Name of the span_iframe to search for */ + fun spanIframeName(): Optional = Optional.ofNullable(spanIframeName) + + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ + fun startingAfter(): Optional = Optional.ofNullable(startingAfter) + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + spanIframeName?.let { put("span_iframe_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): SpanIframeListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [SpanIframeListParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeListParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + private var endingBefore: String? = null + private var ids: Ids? = null + private var limit: Long? = null + private var orgName: String? = null + private var spanIframeName: String? = null + private var startingAfter: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(spanIframeListParams: SpanIframeListParams) = apply { + endingBefore = spanIframeListParams.endingBefore + ids = spanIframeListParams.ids + limit = spanIframeListParams.limit + orgName = spanIframeListParams.orgName + spanIframeName = spanIframeListParams.spanIframeName + startingAfter = spanIframeListParams.startingAfter + additionalHeaders = spanIframeListParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeListParams.additionalQueryParams.toBuilder() + } + + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } + + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) + + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, + * include the query param multiple times + */ + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } + + /** + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun limit(limit: Long) = limit(limit as Long?) + + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) + + /** Filter search results to within a particular organization */ + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) + + /** Name of the span_iframe to search for */ + fun spanIframeName(spanIframeName: String?) = apply { this.spanIframeName = spanIframeName } + + /** Alias for calling [Builder.spanIframeName] with `spanIframeName.orElse(null)`. */ + fun spanIframeName(spanIframeName: Optional) = + spanIframeName(spanIframeName.getOrNull()) + + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } + + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.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 [SpanIframeListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): SpanIframeListParams = + SpanIframeListParams( + endingBefore, + ids, + limit, + orgName, + spanIframeName, + startingAfter, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ + @JsonDeserialize(using = Ids.Deserializer::class) + @JsonSerialize(using = Ids.Serializer::class) + class Ids + private constructor( + private val string: String? = null, + private val strings: List? = null, + private val _json: JsonValue? = null, + ) { + + fun string(): Optional = Optional.ofNullable(string) + + fun strings(): Optional> = Optional.ofNullable(strings) + + fun isString(): Boolean = string != null + + fun isStrings(): Boolean = strings != null + + fun asString(): String = string.getOrThrow("string") + + fun asStrings(): List = strings.getOrThrow("strings") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T { + return when { + string != null -> visitor.visitString(string) + strings != null -> visitor.visitStrings(strings) + else -> visitor.unknown(_json) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ + + override fun toString(): String = + when { + string != null -> "Ids{string=$string}" + strings != null -> "Ids{strings=$strings}" + _json != null -> "Ids{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Ids") + } + + companion object { + + @JvmStatic fun ofString(string: String) = Ids(string = string) + + @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) + } + + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ + interface Visitor { + + fun visitString(string: String): T + + fun visitStrings(strings: List): T + + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw BraintrustInvalidDataException("Unknown Ids: $json") + } + } + + internal class Deserializer : BaseDeserializer(Ids::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Ids { + val json = JsonValue.fromJsonNode(node) + + tryDeserialize(node, jacksonTypeRef())?.let { + return Ids(string = it, _json = json) + } + tryDeserialize(node, jacksonTypeRef>())?.let { + return Ids(strings = it, _json = json) + } + + return Ids(_json = json) + } + } + + internal class Serializer : BaseSerializer(Ids::class) { + + override fun serialize( + value: Ids, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.strings != null -> generator.writeObject(value.strings) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Ids") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeListParams && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && orgName == other.orgName && spanIframeName == other.spanIframeName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(endingBefore, ids, limit, orgName, spanIframeName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "SpanIframeListParams{endingBefore=$endingBefore, ids=$ids, limit=$limit, orgName=$orgName, spanIframeName=$spanIframeName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParams.kt new file mode 100644 index 00000000..0b05cad8 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParams.kt @@ -0,0 +1,682 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Create or replace span_iframe. If there is an existing span_iframe with the same name as the one + * specified in the request, will replace the existing span_iframe with the provided fields + */ +class SpanIframeReplaceParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException 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() + + /** + * Unique identifier for the project that the span iframe belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = body.projectId() + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException 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 url(): String = body.url() + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when you + * want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun postMessage(): Optional = body.postMessage() + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _projectId(): JsonField = body._projectId() + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _url(): JsonField = body._url() + + /** + * 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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _postMessage(): JsonField = body._postMessage() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + @NoAutoDetect + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("project_id") + @ExcludeMissing + private val projectId: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing private val url: JsonField = JsonMissing.of(), + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("post_message") + @ExcludeMissing + private val postMessage: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException 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") + + /** + * Unique identifier for the project that the span iframe belongs under + * + * @throws BraintrustInvalidDataException 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 projectId(): String = projectId.getRequired("project_id") + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException 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 url(): String = url.getRequired("url") + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun postMessage(): Optional = + Optional.ofNullable(postMessage.getNullable("post_message")) + + /** + * 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 [projectId]. + * + * Unlike [projectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_id") @ExcludeMissing fun _projectId(): JsonField = projectId + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + /** + * 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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("post_message") + @ExcludeMissing + fun _postMessage(): JsonField = postMessage + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + name() + projectId() + url() + description() + postMessage() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var projectId: JsonField? = null + private var url: JsonField? = null + private var description: JsonField = JsonMissing.of() + private var postMessage: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + name = body.name + projectId = body.projectId + url = body.url + description = body.description + postMessage = body.postMessage + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Name of the span iframe */ + 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 } + + /** Unique identifier for the project that the span iframe belongs under */ + fun projectId(projectId: String) = projectId(JsonField.of(projectId)) + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun projectId(projectId: JsonField) = apply { this.projectId = projectId } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String) = url(JsonField.of(url)) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + /** Textual description of the span iframe */ + 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 to post messages to the iframe containing the span's data. This is useful + * when you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = postMessage(JsonField.ofNullable(postMessage)) + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postMessage(postMessage: JsonField) = apply { + this.postMessage = postMessage + } + + 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() + * .projectId() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("projectId", projectId), + checkRequired("url", url), + description, + postMessage, + additionalProperties.toImmutable(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && name == other.name && projectId == other.projectId && url == other.url && description == other.description && postMessage == other.postMessage && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, projectId, url, description, postMessage, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{name=$name, projectId=$projectId, url=$url, description=$description, postMessage=$postMessage, additionalProperties=$additionalProperties}" + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeReplaceParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + 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(spanIframeReplaceParams: SpanIframeReplaceParams) = apply { + body = spanIframeReplaceParams.body.toBuilder() + additionalHeaders = spanIframeReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeReplaceParams.additionalQueryParams.toBuilder() + } + + /** Name of the span iframe */ + 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) } + + /** Unique identifier for the project that the span iframe belongs under */ + fun projectId(projectId: String) = apply { body.projectId(projectId) } + + /** + * Sets [Builder.projectId] to an arbitrary JSON value. + * + * You should usually call [Builder.projectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectId(projectId: JsonField) = apply { body.projectId(projectId) } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String) = apply { body.url(url) } + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun url(url: JsonField) = apply { body.url(url) } + + /** Textual description of the span iframe */ + 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 to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = apply { body.postMessage(postMessage) } + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun postMessage(postMessage: JsonField) = apply { body.postMessage(postMessage) } + + 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 [SpanIframeReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .projectId() + * .url() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIframeReplaceParams = + SpanIframeReplaceParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "SpanIframeReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParams.kt new file mode 100644 index 00000000..003e528f --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParams.kt @@ -0,0 +1,201 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import java.util.Objects + +/** Get a span_iframe object by its id */ +class SpanIframeRetrieveParams +private constructor( + private val spanIframeId: String, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** SpanIframe id */ + fun spanIframeId(): String = spanIframeId + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + fun getPathParam(index: Int): String { + return when (index) { + 0 -> spanIframeId + else -> "" + } + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeRetrieveParams]. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeRetrieveParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + private var spanIframeId: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(spanIframeRetrieveParams: SpanIframeRetrieveParams) = apply { + spanIframeId = spanIframeRetrieveParams.spanIframeId + additionalHeaders = spanIframeRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeRetrieveParams.additionalQueryParams.toBuilder() + } + + /** SpanIframe id */ + fun spanIframeId(spanIframeId: String) = apply { this.spanIframeId = spanIframeId } + + 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 [SpanIframeRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIframeRetrieveParams = + SpanIframeRetrieveParams( + checkRequired("spanIframeId", spanIframeId), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeRetrieveParams && spanIframeId == other.spanIframeId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanIframeId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "SpanIframeRetrieveParams{spanIframeId=$spanIframeId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParams.kt new file mode 100644 index 00000000..d5fa952c --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParams.kt @@ -0,0 +1,623 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.ExcludeMissing +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException +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 java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Partially update a span_iframe object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ +class SpanIframeUpdateParams +private constructor( + private val spanIframeId: String, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** SpanIframe id */ + fun spanIframeId(): String = spanIframeId + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun description(): Optional = body.description() + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when you + * want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun postMessage(): Optional = body.postMessage() + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun url(): Optional = body.url() + + /** + * 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 [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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _postMessage(): JsonField = body._postMessage() + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _url(): JsonField = body._url() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + fun getPathParam(index: Int): String { + return when (index) { + 0 -> spanIframeId + else -> "" + } + } + + @NoAutoDetect + class Body + @JsonCreator + private constructor( + @JsonProperty("description") + @ExcludeMissing + private val description: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("post_message") + @ExcludeMissing + private val postMessage: JsonField = JsonMissing.of(), + @JsonProperty("url") @ExcludeMissing private val url: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), + ) { + + /** + * Textual description of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun description(): Optional = + Optional.ofNullable(description.getNullable("description")) + + /** + * Name of the span iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun postMessage(): Optional = + Optional.ofNullable(postMessage.getNullable("post_message")) + + /** + * URL to embed the project viewer in an iframe + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun url(): Optional = Optional.ofNullable(url.getNullable("url")) + + /** + * 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 [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 [postMessage]. + * + * Unlike [postMessage], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("post_message") + @ExcludeMissing + fun _postMessage(): JsonField = postMessage + + /** + * Returns the raw JSON value of [url]. + * + * Unlike [url], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("url") @ExcludeMissing fun _url(): JsonField = url + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + description() + name() + postMessage() + url() + validated = true + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var description: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var postMessage: JsonField = JsonMissing.of() + private var url: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + description = body.description + name = body.name + postMessage = body.postMessage + url = body.url + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** Textual description of the span iframe */ + 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 + } + + /** Name of the span iframe */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } + + /** + * Whether to post messages to the iframe containing the span's data. This is useful + * when you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = postMessage(JsonField.ofNullable(postMessage)) + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postMessage(postMessage: JsonField) = apply { + this.postMessage = postMessage + } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String?) = url(JsonField.ofNullable(url)) + + /** Alias for calling [Builder.url] with `url.orElse(null)`. */ + fun url(url: Optional) = url(url.getOrNull()) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun url(url: JsonField) = apply { this.url = url } + + 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. + */ + fun build(): Body = + Body(description, name, postMessage, url, additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Body && description == other.description && name == other.name && postMessage == other.postMessage && url == other.url && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(description, name, postMessage, url, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{description=$description, name=$name, postMessage=$postMessage, url=$url, additionalProperties=$additionalProperties}" + } + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SpanIframeUpdateParams]. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SpanIframeUpdateParams]. */ + @NoAutoDetect + class Builder internal constructor() { + + private var spanIframeId: 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(spanIframeUpdateParams: SpanIframeUpdateParams) = apply { + spanIframeId = spanIframeUpdateParams.spanIframeId + body = spanIframeUpdateParams.body.toBuilder() + additionalHeaders = spanIframeUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = spanIframeUpdateParams.additionalQueryParams.toBuilder() + } + + /** SpanIframe id */ + fun spanIframeId(spanIframeId: String) = apply { this.spanIframeId = spanIframeId } + + /** Textual description of the span iframe */ + 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) } + + /** Name of the span iframe */ + fun name(name: String?) = apply { body.name(name) } + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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) } + + /** + * Whether to post messages to the iframe containing the span's data. This is useful when + * you want to render more data than fits in the URL. + */ + fun postMessage(postMessage: Boolean?) = apply { body.postMessage(postMessage) } + + /** + * Alias for [Builder.postMessage]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun postMessage(postMessage: Boolean) = postMessage(postMessage as Boolean?) + + /** Alias for calling [Builder.postMessage] with `postMessage.orElse(null)`. */ + fun postMessage(postMessage: Optional) = postMessage(postMessage.getOrNull()) + + /** + * Sets [Builder.postMessage] to an arbitrary JSON value. + * + * You should usually call [Builder.postMessage] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun postMessage(postMessage: JsonField) = apply { body.postMessage(postMessage) } + + /** URL to embed the project viewer in an iframe */ + fun url(url: String?) = apply { body.url(url) } + + /** Alias for calling [Builder.url] with `url.orElse(null)`. */ + fun url(url: Optional) = url(url.getOrNull()) + + /** + * Sets [Builder.url] to an arbitrary JSON value. + * + * You should usually call [Builder.url] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun url(url: JsonField) = apply { body.url(url) } + + 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 [SpanIframeUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .spanIframeId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SpanIframeUpdateParams = + SpanIframeUpdateParams( + checkRequired("spanIframeId", spanIframeId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanIframeUpdateParams && spanIframeId == other.spanIframeId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(spanIframeId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "SpanIframeUpdateParams{spanIframeId=$spanIframeId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanType.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanType.kt new file mode 100644 index 00000000..2c558123 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SpanType.kt @@ -0,0 +1,130 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +/** Type of the span, for display purposes only */ +class SpanType @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 LLM = of("llm") + + @JvmField val SCORE = of("score") + + @JvmField val FUNCTION = of("function") + + @JvmField val EVAL = of("eval") + + @JvmField val TASK = of("task") + + @JvmField val TOOL = of("tool") + + @JvmStatic fun of(value: String) = SpanType(JsonField.of(value)) + } + + /** An enum containing [SpanType]'s known values. */ + enum class Known { + LLM, + SCORE, + FUNCTION, + EVAL, + TASK, + TOOL, + } + + /** + * An enum containing [SpanType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [SpanType] 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 { + LLM, + SCORE, + FUNCTION, + EVAL, + TASK, + TOOL, + /** An enum member indicating that [SpanType] 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) { + LLM -> Value.LLM + SCORE -> Value.SCORE + FUNCTION -> Value.FUNCTION + EVAL -> Value.EVAL + TASK -> Value.TASK + TOOL -> Value.TOOL + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + LLM -> Known.LLM + SCORE -> Known.SCORE + FUNCTION -> Known.FUNCTION + EVAL -> Known.EVAL + TASK -> Known.TASK + TOOL -> Known.TOOL + else -> throw BraintrustInvalidDataException("Unknown SpanType: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SpanType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponse.kt index 4b2fdaf6..78210f20 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponse.kt @@ -7,199 +7,304 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Summary of a dataset */ -@JsonDeserialize(builder = SummarizeDatasetResponse.Builder::class) @NoAutoDetect class SummarizeDatasetResponse +@JsonCreator private constructor( - private val projectName: JsonField, - private val datasetName: JsonField, - private val projectUrl: JsonField, - private val datasetUrl: JsonField, - private val dataSummary: JsonField, - private val additionalProperties: Map, + @JsonProperty("dataset_name") + @ExcludeMissing + private val datasetName: JsonField = JsonMissing.of(), + @JsonProperty("dataset_url") + @ExcludeMissing + private val datasetUrl: JsonField = JsonMissing.of(), + @JsonProperty("project_name") + @ExcludeMissing + private val projectName: JsonField = JsonMissing.of(), + @JsonProperty("project_url") + @ExcludeMissing + private val projectUrl: JsonField = JsonMissing.of(), + @JsonProperty("data_summary") + @ExcludeMissing + private val dataSummary: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * Name of the dataset + * + * @throws BraintrustInvalidDataException 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 datasetName(): String = datasetName.getRequired("dataset_name") - private var hashCode: Int = 0 + /** + * URL to the dataset's page in the Braintrust app + * + * @throws BraintrustInvalidDataException 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 datasetUrl(): String = datasetUrl.getRequired("dataset_url") - /** Name of the project that the dataset belongs to */ + /** + * Name of the project that the dataset belongs to + * + * @throws BraintrustInvalidDataException 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 projectName(): String = projectName.getRequired("project_name") - /** Name of the dataset */ - fun datasetName(): String = datasetName.getRequired("dataset_name") - - /** URL to the project's page in the Braintrust app */ + /** + * URL to the project's page in the Braintrust app + * + * @throws BraintrustInvalidDataException 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 projectUrl(): String = projectUrl.getRequired("project_url") - /** URL to the dataset's page in the Braintrust app */ - fun datasetUrl(): String = datasetUrl.getRequired("dataset_url") - - /** Summary of a dataset's data */ + /** + * Summary of a dataset's data + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun dataSummary(): Optional = Optional.ofNullable(dataSummary.getNullable("data_summary")) - /** Name of the project that the dataset belongs to */ - @JsonProperty("project_name") @ExcludeMissing fun _projectName() = projectName - - /** Name of the dataset */ - @JsonProperty("dataset_name") @ExcludeMissing fun _datasetName() = datasetName - - /** URL to the project's page in the Braintrust app */ - @JsonProperty("project_url") @ExcludeMissing fun _projectUrl() = projectUrl - - /** URL to the dataset's page in the Braintrust app */ - @JsonProperty("dataset_url") @ExcludeMissing fun _datasetUrl() = datasetUrl - - /** Summary of a dataset's data */ - @JsonProperty("data_summary") @ExcludeMissing fun _dataSummary() = dataSummary + /** + * Returns the raw JSON value of [datasetName]. + * + * Unlike [datasetName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_name") + @ExcludeMissing + fun _datasetName(): JsonField = datasetName + + /** + * Returns the raw JSON value of [datasetUrl]. + * + * Unlike [datasetUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dataset_url") @ExcludeMissing fun _datasetUrl(): JsonField = datasetUrl + + /** + * Returns the raw JSON value of [projectName]. + * + * Unlike [projectName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_name") + @ExcludeMissing + fun _projectName(): JsonField = projectName + + /** + * Returns the raw JSON value of [projectUrl]. + * + * Unlike [projectUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_url") @ExcludeMissing fun _projectUrl(): JsonField = projectUrl + + /** + * Returns the raw JSON value of [dataSummary]. + * + * Unlike [dataSummary], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data_summary") + @ExcludeMissing + fun _dataSummary(): JsonField = dataSummary @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): SummarizeDatasetResponse = apply { - if (!validated) { - projectName() - datasetName() - projectUrl() - datasetUrl() - dataSummary().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): SummarizeDatasetResponse = apply { + if (validated) { + return@apply } - return other is SummarizeDatasetResponse && - this.projectName == other.projectName && - this.datasetName == other.datasetName && - this.projectUrl == other.projectUrl && - this.datasetUrl == other.datasetUrl && - this.dataSummary == other.dataSummary && - this.additionalProperties == other.additionalProperties + datasetName() + datasetUrl() + projectName() + projectUrl() + dataSummary().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectName, - datasetName, - projectUrl, - datasetUrl, - dataSummary, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SummarizeDatasetResponse{projectName=$projectName, datasetName=$datasetName, projectUrl=$projectUrl, datasetUrl=$datasetUrl, dataSummary=$dataSummary, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [SummarizeDatasetResponse]. + * + * The following fields are required: + * ```java + * .datasetName() + * .datasetUrl() + * .projectName() + * .projectUrl() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [SummarizeDatasetResponse]. */ + class Builder internal constructor() { - private var projectName: JsonField = JsonMissing.of() - private var datasetName: JsonField = JsonMissing.of() - private var projectUrl: JsonField = JsonMissing.of() - private var datasetUrl: JsonField = JsonMissing.of() + private var datasetName: JsonField? = null + private var datasetUrl: JsonField? = null + private var projectName: JsonField? = null + private var projectUrl: JsonField? = null private var dataSummary: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(summarizeDatasetResponse: SummarizeDatasetResponse) = apply { - this.projectName = summarizeDatasetResponse.projectName - this.datasetName = summarizeDatasetResponse.datasetName - this.projectUrl = summarizeDatasetResponse.projectUrl - this.datasetUrl = summarizeDatasetResponse.datasetUrl - this.dataSummary = summarizeDatasetResponse.dataSummary - additionalProperties(summarizeDatasetResponse.additionalProperties) + datasetName = summarizeDatasetResponse.datasetName + datasetUrl = summarizeDatasetResponse.datasetUrl + projectName = summarizeDatasetResponse.projectName + projectUrl = summarizeDatasetResponse.projectUrl + dataSummary = summarizeDatasetResponse.dataSummary + additionalProperties = summarizeDatasetResponse.additionalProperties.toMutableMap() } - /** Name of the project that the dataset belongs to */ - fun projectName(projectName: String) = projectName(JsonField.of(projectName)) - - /** Name of the project that the dataset belongs to */ - @JsonProperty("project_name") - @ExcludeMissing - fun projectName(projectName: JsonField) = apply { this.projectName = projectName } - /** Name of the dataset */ fun datasetName(datasetName: String) = datasetName(JsonField.of(datasetName)) - /** Name of the dataset */ - @JsonProperty("dataset_name") - @ExcludeMissing + /** + * Sets [Builder.datasetName] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun datasetName(datasetName: JsonField) = apply { this.datasetName = datasetName } - /** URL to the project's page in the Braintrust app */ - fun projectUrl(projectUrl: String) = projectUrl(JsonField.of(projectUrl)) - - /** URL to the project's page in the Braintrust app */ - @JsonProperty("project_url") - @ExcludeMissing - fun projectUrl(projectUrl: JsonField) = apply { this.projectUrl = projectUrl } - /** URL to the dataset's page in the Braintrust app */ fun datasetUrl(datasetUrl: String) = datasetUrl(JsonField.of(datasetUrl)) - /** URL to the dataset's page in the Braintrust app */ - @JsonProperty("dataset_url") - @ExcludeMissing + /** + * Sets [Builder.datasetUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.datasetUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun datasetUrl(datasetUrl: JsonField) = apply { this.datasetUrl = datasetUrl } - /** Summary of a dataset's data */ - fun dataSummary(dataSummary: DataSummary) = dataSummary(JsonField.of(dataSummary)) + /** Name of the project that the dataset belongs to */ + fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + + /** + * Sets [Builder.projectName] to an arbitrary JSON value. + * + * You should usually call [Builder.projectName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectName(projectName: JsonField) = apply { this.projectName = projectName } + + /** URL to the project's page in the Braintrust app */ + fun projectUrl(projectUrl: String) = projectUrl(JsonField.of(projectUrl)) + + /** + * Sets [Builder.projectUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.projectUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectUrl(projectUrl: JsonField) = apply { this.projectUrl = projectUrl } /** Summary of a dataset's data */ - @JsonProperty("data_summary") - @ExcludeMissing + fun dataSummary(dataSummary: DataSummary?) = dataSummary(JsonField.ofNullable(dataSummary)) + + /** Alias for calling [Builder.dataSummary] with `dataSummary.orElse(null)`. */ + fun dataSummary(dataSummary: Optional) = dataSummary(dataSummary.getOrNull()) + + /** + * Sets [Builder.dataSummary] to an arbitrary JSON value. + * + * You should usually call [Builder.dataSummary] with a well-typed [DataSummary] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun dataSummary(dataSummary: JsonField) = apply { this.dataSummary = dataSummary } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [SummarizeDatasetResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .datasetName() + * .datasetUrl() + * .projectName() + * .projectUrl() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): SummarizeDatasetResponse = SummarizeDatasetResponse( - projectName, - datasetName, - projectUrl, - datasetUrl, + checkRequired("datasetName", datasetName), + checkRequired("datasetUrl", datasetUrl), + checkRequired("projectName", projectName), + checkRequired("projectUrl", projectUrl), dataSummary, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SummarizeDatasetResponse && datasetName == other.datasetName && datasetUrl == other.datasetUrl && projectName == other.projectName && projectUrl == other.projectUrl && dataSummary == other.dataSummary && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(datasetName, datasetUrl, projectName, projectUrl, dataSummary, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SummarizeDatasetResponse{datasetName=$datasetName, datasetUrl=$datasetUrl, projectName=$projectName, projectUrl=$projectUrl, dataSummary=$dataSummary, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponse.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponse.kt index 8a391f6a..1c8a412a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponse.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponse.kt @@ -7,394 +7,558 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Summary of an experiment */ -@JsonDeserialize(builder = SummarizeExperimentResponse.Builder::class) @NoAutoDetect class SummarizeExperimentResponse +@JsonCreator private constructor( - private val projectName: JsonField, - private val experimentName: JsonField, - private val projectUrl: JsonField, - private val experimentUrl: JsonField, - private val comparisonExperimentName: JsonField, - private val scores: JsonField, - private val metrics: JsonField, - private val additionalProperties: Map, + @JsonProperty("experiment_name") + @ExcludeMissing + private val experimentName: JsonField = JsonMissing.of(), + @JsonProperty("experiment_url") + @ExcludeMissing + private val experimentUrl: JsonField = JsonMissing.of(), + @JsonProperty("project_name") + @ExcludeMissing + private val projectName: JsonField = JsonMissing.of(), + @JsonProperty("project_url") + @ExcludeMissing + private val projectUrl: JsonField = JsonMissing.of(), + @JsonProperty("comparison_experiment_name") + @ExcludeMissing + private val comparisonExperimentName: JsonField = JsonMissing.of(), + @JsonProperty("metrics") + @ExcludeMissing + private val metrics: JsonField = JsonMissing.of(), + @JsonProperty("scores") + @ExcludeMissing + private val scores: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false + /** + * Name of the experiment + * + * @throws BraintrustInvalidDataException 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 experimentName(): String = experimentName.getRequired("experiment_name") - private var hashCode: Int = 0 + /** + * URL to the experiment's page in the Braintrust app + * + * @throws BraintrustInvalidDataException 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 experimentUrl(): String = experimentUrl.getRequired("experiment_url") - /** Name of the project that the experiment belongs to */ + /** + * Name of the project that the experiment belongs to + * + * @throws BraintrustInvalidDataException 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 projectName(): String = projectName.getRequired("project_name") - /** Name of the experiment */ - fun experimentName(): String = experimentName.getRequired("experiment_name") - - /** URL to the project's page in the Braintrust app */ + /** + * URL to the project's page in the Braintrust app + * + * @throws BraintrustInvalidDataException 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 projectUrl(): String = projectUrl.getRequired("project_url") - /** URL to the experiment's page in the Braintrust app */ - fun experimentUrl(): String = experimentUrl.getRequired("experiment_url") - - /** The experiment which scores are baselined against */ + /** + * The experiment which scores are baselined against + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun comparisonExperimentName(): Optional = Optional.ofNullable(comparisonExperimentName.getNullable("comparison_experiment_name")) - /** Summary of the experiment's scores */ - fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - - /** Summary of the experiment's metrics */ + /** + * Summary of the experiment's metrics + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun metrics(): Optional = Optional.ofNullable(metrics.getNullable("metrics")) - /** Name of the project that the experiment belongs to */ - @JsonProperty("project_name") @ExcludeMissing fun _projectName() = projectName - - /** Name of the experiment */ - @JsonProperty("experiment_name") @ExcludeMissing fun _experimentName() = experimentName - - /** URL to the project's page in the Braintrust app */ - @JsonProperty("project_url") @ExcludeMissing fun _projectUrl() = projectUrl - - /** URL to the experiment's page in the Braintrust app */ - @JsonProperty("experiment_url") @ExcludeMissing fun _experimentUrl() = experimentUrl + /** + * Summary of the experiment's scores + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun scores(): Optional = Optional.ofNullable(scores.getNullable("scores")) - /** The experiment which scores are baselined against */ + /** + * Returns the raw JSON value of [experimentName]. + * + * Unlike [experimentName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("experiment_name") + @ExcludeMissing + fun _experimentName(): JsonField = experimentName + + /** + * Returns the raw JSON value of [experimentUrl]. + * + * Unlike [experimentUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("experiment_url") + @ExcludeMissing + fun _experimentUrl(): JsonField = experimentUrl + + /** + * Returns the raw JSON value of [projectName]. + * + * Unlike [projectName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_name") + @ExcludeMissing + fun _projectName(): JsonField = projectName + + /** + * Returns the raw JSON value of [projectUrl]. + * + * Unlike [projectUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("project_url") @ExcludeMissing fun _projectUrl(): JsonField = projectUrl + + /** + * Returns the raw JSON value of [comparisonExperimentName]. + * + * Unlike [comparisonExperimentName], this method doesn't throw if the JSON field has an + * unexpected type. + */ @JsonProperty("comparison_experiment_name") @ExcludeMissing - fun _comparisonExperimentName() = comparisonExperimentName - - /** Summary of the experiment's scores */ - @JsonProperty("scores") @ExcludeMissing fun _scores() = scores - - /** Summary of the experiment's metrics */ - @JsonProperty("metrics") @ExcludeMissing fun _metrics() = metrics + fun _comparisonExperimentName(): JsonField = comparisonExperimentName + + /** + * Returns the raw JSON value of [metrics]. + * + * Unlike [metrics], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("metrics") @ExcludeMissing fun _metrics(): JsonField = metrics + + /** + * Returns the raw JSON value of [scores]. + * + * Unlike [scores], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("scores") @ExcludeMissing fun _scores(): JsonField = scores @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): SummarizeExperimentResponse = apply { - if (!validated) { - projectName() - experimentName() - projectUrl() - experimentUrl() - comparisonExperimentName() - scores().map { it.validate() } - metrics().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): SummarizeExperimentResponse = apply { + if (validated) { + return@apply } - return other is SummarizeExperimentResponse && - this.projectName == other.projectName && - this.experimentName == other.experimentName && - this.projectUrl == other.projectUrl && - this.experimentUrl == other.experimentUrl && - this.comparisonExperimentName == other.comparisonExperimentName && - this.scores == other.scores && - this.metrics == other.metrics && - this.additionalProperties == other.additionalProperties + experimentName() + experimentUrl() + projectName() + projectUrl() + comparisonExperimentName() + metrics().ifPresent { it.validate() } + scores().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - projectName, - experimentName, - projectUrl, - experimentUrl, - comparisonExperimentName, - scores, - metrics, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "SummarizeExperimentResponse{projectName=$projectName, experimentName=$experimentName, projectUrl=$projectUrl, experimentUrl=$experimentUrl, comparisonExperimentName=$comparisonExperimentName, scores=$scores, metrics=$metrics, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [SummarizeExperimentResponse]. + * + * The following fields are required: + * ```java + * .experimentName() + * .experimentUrl() + * .projectName() + * .projectUrl() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [SummarizeExperimentResponse]. */ + class Builder internal constructor() { - private var projectName: JsonField = JsonMissing.of() - private var experimentName: JsonField = JsonMissing.of() - private var projectUrl: JsonField = JsonMissing.of() - private var experimentUrl: JsonField = JsonMissing.of() + private var experimentName: JsonField? = null + private var experimentUrl: JsonField? = null + private var projectName: JsonField? = null + private var projectUrl: JsonField? = null private var comparisonExperimentName: JsonField = JsonMissing.of() - private var scores: JsonField = JsonMissing.of() private var metrics: JsonField = JsonMissing.of() + private var scores: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(summarizeExperimentResponse: SummarizeExperimentResponse) = apply { - this.projectName = summarizeExperimentResponse.projectName - this.experimentName = summarizeExperimentResponse.experimentName - this.projectUrl = summarizeExperimentResponse.projectUrl - this.experimentUrl = summarizeExperimentResponse.experimentUrl - this.comparisonExperimentName = summarizeExperimentResponse.comparisonExperimentName - this.scores = summarizeExperimentResponse.scores - this.metrics = summarizeExperimentResponse.metrics - additionalProperties(summarizeExperimentResponse.additionalProperties) + experimentName = summarizeExperimentResponse.experimentName + experimentUrl = summarizeExperimentResponse.experimentUrl + projectName = summarizeExperimentResponse.projectName + projectUrl = summarizeExperimentResponse.projectUrl + comparisonExperimentName = summarizeExperimentResponse.comparisonExperimentName + metrics = summarizeExperimentResponse.metrics + scores = summarizeExperimentResponse.scores + additionalProperties = summarizeExperimentResponse.additionalProperties.toMutableMap() } - /** Name of the project that the experiment belongs to */ - fun projectName(projectName: String) = projectName(JsonField.of(projectName)) - - /** Name of the project that the experiment belongs to */ - @JsonProperty("project_name") - @ExcludeMissing - fun projectName(projectName: JsonField) = apply { this.projectName = projectName } - /** Name of the experiment */ fun experimentName(experimentName: String) = experimentName(JsonField.of(experimentName)) - /** Name of the experiment */ - @JsonProperty("experiment_name") - @ExcludeMissing + /** + * Sets [Builder.experimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.experimentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun experimentName(experimentName: JsonField) = apply { this.experimentName = experimentName } - /** URL to the project's page in the Braintrust app */ - fun projectUrl(projectUrl: String) = projectUrl(JsonField.of(projectUrl)) - - /** URL to the project's page in the Braintrust app */ - @JsonProperty("project_url") - @ExcludeMissing - fun projectUrl(projectUrl: JsonField) = apply { this.projectUrl = projectUrl } - /** URL to the experiment's page in the Braintrust app */ fun experimentUrl(experimentUrl: String) = experimentUrl(JsonField.of(experimentUrl)) - /** URL to the experiment's page in the Braintrust app */ - @JsonProperty("experiment_url") - @ExcludeMissing + /** + * Sets [Builder.experimentUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.experimentUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun experimentUrl(experimentUrl: JsonField) = apply { this.experimentUrl = experimentUrl } - /** The experiment which scores are baselined against */ - fun comparisonExperimentName(comparisonExperimentName: String) = - comparisonExperimentName(JsonField.of(comparisonExperimentName)) + /** Name of the project that the experiment belongs to */ + fun projectName(projectName: String) = projectName(JsonField.of(projectName)) + + /** + * Sets [Builder.projectName] to an arbitrary JSON value. + * + * You should usually call [Builder.projectName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectName(projectName: JsonField) = apply { this.projectName = projectName } + + /** URL to the project's page in the Braintrust app */ + fun projectUrl(projectUrl: String) = projectUrl(JsonField.of(projectUrl)) + + /** + * Sets [Builder.projectUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.projectUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun projectUrl(projectUrl: JsonField) = apply { this.projectUrl = projectUrl } /** The experiment which scores are baselined against */ - @JsonProperty("comparison_experiment_name") - @ExcludeMissing + fun comparisonExperimentName(comparisonExperimentName: String?) = + comparisonExperimentName(JsonField.ofNullable(comparisonExperimentName)) + + /** + * Alias for calling [Builder.comparisonExperimentName] with + * `comparisonExperimentName.orElse(null)`. + */ + fun comparisonExperimentName(comparisonExperimentName: Optional) = + comparisonExperimentName(comparisonExperimentName.getOrNull()) + + /** + * Sets [Builder.comparisonExperimentName] to an arbitrary JSON value. + * + * You should usually call [Builder.comparisonExperimentName] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ fun comparisonExperimentName(comparisonExperimentName: JsonField) = apply { this.comparisonExperimentName = comparisonExperimentName } - /** Summary of the experiment's scores */ - fun scores(scores: Scores) = scores(JsonField.of(scores)) + /** Summary of the experiment's metrics */ + fun metrics(metrics: Metrics?) = metrics(JsonField.ofNullable(metrics)) + + /** Alias for calling [Builder.metrics] with `metrics.orElse(null)`. */ + fun metrics(metrics: Optional) = metrics(metrics.getOrNull()) + + /** + * Sets [Builder.metrics] to an arbitrary JSON value. + * + * You should usually call [Builder.metrics] with a well-typed [Metrics] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun metrics(metrics: JsonField) = apply { this.metrics = metrics } /** Summary of the experiment's scores */ - @JsonProperty("scores") - @ExcludeMissing - fun scores(scores: JsonField) = apply { this.scores = scores } + fun scores(scores: Scores?) = scores(JsonField.ofNullable(scores)) - /** Summary of the experiment's metrics */ - fun metrics(metrics: Metrics) = metrics(JsonField.of(metrics)) + /** Alias for calling [Builder.scores] with `scores.orElse(null)`. */ + fun scores(scores: Optional) = scores(scores.getOrNull()) - /** Summary of the experiment's metrics */ - @JsonProperty("metrics") - @ExcludeMissing - fun metrics(metrics: JsonField) = apply { this.metrics = metrics } + /** + * Sets [Builder.scores] to an arbitrary JSON value. + * + * You should usually call [Builder.scores] with a well-typed [Scores] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun scores(scores: JsonField) = apply { this.scores = scores } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [SummarizeExperimentResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .experimentName() + * .experimentUrl() + * .projectName() + * .projectUrl() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): SummarizeExperimentResponse = SummarizeExperimentResponse( - projectName, - experimentName, - projectUrl, - experimentUrl, + checkRequired("experimentName", experimentName), + checkRequired("experimentUrl", experimentUrl), + checkRequired("projectName", projectName), + checkRequired("projectUrl", projectUrl), comparisonExperimentName, - scores, metrics, - additionalProperties.toUnmodifiable(), + scores, + additionalProperties.toImmutable(), ) } /** Summary of the experiment's metrics */ - @JsonDeserialize(builder = Metrics.Builder::class) @NoAutoDetect class Metrics + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Metrics = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Metrics = apply { + if (validated) { + return@apply } - return other is Metrics && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Metrics{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Metrics]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Metrics]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(metrics: Metrics) = apply { - additionalProperties(metrics.additionalProperties) + additionalProperties = metrics.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Metrics = Metrics(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Metrics]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Metrics = Metrics(additionalProperties.toImmutable()) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Metrics && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Metrics{additionalProperties=$additionalProperties}" } /** Summary of the experiment's scores */ - @JsonDeserialize(builder = Scores.Builder::class) @NoAutoDetect class Scores + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): Scores = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Scores = apply { + if (validated) { + return@apply } - return other is Scores && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "Scores{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [Scores]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Scores]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(scores: Scores) = apply { - additionalProperties(scores.additionalProperties) + additionalProperties = scores.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): Scores = Scores(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Scores]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Scores = Scores(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is Scores && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "Scores{additionalProperties=$additionalProperties}" } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is SummarizeExperimentResponse && experimentName == other.experimentName && experimentUrl == other.experimentUrl && projectName == other.projectName && projectUrl == other.projectUrl && comparisonExperimentName == other.comparisonExperimentName && metrics == other.metrics && scores == other.scores && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(experimentName, experimentUrl, projectName, projectUrl, comparisonExperimentName, metrics, scores, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SummarizeExperimentResponse{experimentName=$experimentName, experimentUrl=$experimentUrl, projectName=$projectName, projectUrl=$projectUrl, comparisonExperimentName=$comparisonExperimentName, metrics=$metrics, scores=$scores, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Task.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Task.kt deleted file mode 100644 index 77b56f67..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/Task.kt +++ /dev/null @@ -1,157 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.databind.annotation.JsonDeserialize -import java.util.Objects - -@JsonDeserialize(builder = Task.Builder::class) -@NoAutoDetect -class Task -private constructor( - private val type: JsonField, - private val additionalProperties: Map, -) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Task = apply { - if (!validated) { - type() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Task && - this.type == other.type && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(type, additionalProperties) - } - return hashCode - } - - override fun toString() = "Task{type=$type, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var type: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(task: Task) = apply { - this.type = task.type - additionalProperties(task.additionalProperties) - } - - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Task = Task(type, additionalProperties.toUnmodifiable()) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val TASK = Type(JsonField.of("task")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - TASK, - } - - enum class Value { - TASK, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - TASK -> Value.TASK - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - TASK -> Known.TASK - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ToolChoice.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ToolChoice.kt deleted file mode 100644 index b650da4e..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ToolChoice.kt +++ /dev/null @@ -1,436 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.BaseDeserializer -import com.braintrustdata.api.core.BaseSerializer -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.ExcludeMissing -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonMissing -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -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.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.ObjectCodec -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import java.util.Objects -import java.util.Optional - -@JsonDeserialize(using = ToolChoice.Deserializer::class) -@JsonSerialize(using = ToolChoice.Serializer::class) -class ToolChoice -private constructor( - private val auto: Auto? = null, - private val none: None? = null, - private val function: Function? = null, - private val _json: JsonValue? = null, -) { - - private var validated: Boolean = false - - fun auto(): Optional = Optional.ofNullable(auto) - - fun none(): Optional = Optional.ofNullable(none) - - fun function(): Optional = Optional.ofNullable(function) - - fun isAuto(): Boolean = auto != null - - fun isNone(): Boolean = none != null - - fun isFunction(): Boolean = function != null - - fun asAuto(): Auto = auto.getOrThrow("auto") - - fun asNone(): None = none.getOrThrow("none") - - fun asFunction(): Function = function.getOrThrow("function") - - fun _json(): Optional = Optional.ofNullable(_json) - - fun accept(visitor: Visitor): T { - return when { - auto != null -> visitor.visitAuto(auto) - none != null -> visitor.visitNone(none) - function != null -> visitor.visitFunction(function) - else -> visitor.unknown(_json) - } - } - - fun validate(): ToolChoice = apply { - if (!validated) { - if (auto == null && none == null && function == null) { - throw BraintrustInvalidDataException("Unknown ToolChoice: $_json") - } - function?.validate() - validated = true - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ToolChoice && - this.auto == other.auto && - this.none == other.none && - this.function == other.function - } - - override fun hashCode(): Int { - return Objects.hash( - auto, - none, - function, - ) - } - - override fun toString(): String { - return when { - auto != null -> "ToolChoice{auto=$auto}" - none != null -> "ToolChoice{none=$none}" - function != null -> "ToolChoice{function=$function}" - _json != null -> "ToolChoice{_unknown=$_json}" - else -> throw IllegalStateException("Invalid ToolChoice") - } - } - - companion object { - - @JvmStatic fun ofAuto(auto: Auto) = ToolChoice(auto = auto) - - @JvmStatic fun ofNone(none: None) = ToolChoice(none = none) - - @JvmStatic fun ofFunction(function: Function) = ToolChoice(function = function) - } - - interface Visitor { - - fun visitAuto(auto: Auto): T - - fun visitNone(none: None): T - - fun visitFunction(function: Function): T - - fun unknown(json: JsonValue?): T { - throw BraintrustInvalidDataException("Unknown ToolChoice: $json") - } - } - - class Deserializer : BaseDeserializer(ToolChoice::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): ToolChoice { - val json = JsonValue.fromJsonNode(node) - tryDeserialize(node, jacksonTypeRef())?.let { - return ToolChoice(auto = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef())?.let { - return ToolChoice(none = it, _json = json) - } - tryDeserialize(node, jacksonTypeRef()) { it.validate() } - ?.let { - return ToolChoice(function = it, _json = json) - } - - return ToolChoice(_json = json) - } - } - - class Serializer : BaseSerializer(ToolChoice::class) { - - override fun serialize( - value: ToolChoice, - generator: JsonGenerator, - provider: SerializerProvider - ) { - when { - value.auto != null -> generator.writeObject(value.auto) - value.none != null -> generator.writeObject(value.none) - value.function != null -> generator.writeObject(value.function) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid ToolChoice") - } - } - } - - class Auto - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Auto && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val AUTO = Auto(JsonField.of("auto")) - - @JvmStatic fun of(value: String) = Auto(JsonField.of(value)) - } - - enum class Known { - AUTO, - } - - enum class Value { - AUTO, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - AUTO -> Value.AUTO - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - AUTO -> Known.AUTO - else -> throw BraintrustInvalidDataException("Unknown Auto: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - class None - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is None && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val NONE = None(JsonField.of("none")) - - @JvmStatic fun of(value: String) = None(JsonField.of(value)) - } - - enum class Known { - NONE, - } - - enum class Value { - NONE, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - NONE -> Value.NONE - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - NONE -> Known.NONE - else -> throw BraintrustInvalidDataException("Unknown None: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - - @JsonDeserialize(builder = Function.Builder::class) - @NoAutoDetect - class Function - private constructor( - private val type: JsonField, - private val function: JsonField, - private val additionalProperties: Map, - ) { - - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun type(): Type = type.getRequired("type") - - fun function(): FunctionToolChoice = function.getRequired("function") - - @JsonProperty("type") @ExcludeMissing fun _type() = type - - @JsonProperty("function") @ExcludeMissing fun _function() = function - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties - - fun validate(): Function = apply { - if (!validated) { - type() - function().validate() - validated = true - } - } - - fun toBuilder() = Builder().from(this) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Function && - this.type == other.type && - this.function == other.function && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - type, - function, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "Function{type=$type, function=$function, additionalProperties=$additionalProperties}" - - companion object { - - @JvmStatic fun builder() = Builder() - } - - class Builder { - - private var type: JsonField = JsonMissing.of() - private var function: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(function: Function) = apply { - this.type = function.type - this.function = function.function - additionalProperties(function.additionalProperties) - } - - fun type(type: Type) = type(JsonField.of(type)) - - @JsonProperty("type") - @ExcludeMissing - fun type(type: JsonField) = apply { this.type = type } - - fun function(function: FunctionToolChoice) = function(JsonField.of(function)) - - @JsonProperty("function") - @ExcludeMissing - fun function(function: JsonField) = apply { - this.function = function - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) - } - - @JsonAnySetter - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun build(): Function = - Function( - type, - function, - additionalProperties.toUnmodifiable(), - ) - } - - class Type - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Type && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val FUNCTION = Type(JsonField.of("function")) - - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } - - enum class Known { - FUNCTION, - } - - enum class Value { - FUNCTION, - _UNKNOWN, - } - - fun value(): Value = - when (this) { - FUNCTION -> Value.FUNCTION - else -> Value._UNKNOWN - } - - fun known(): Known = - when (this) { - FUNCTION -> Known.FUNCTION - else -> throw BraintrustInvalidDataException("Unknown Type: $value") - } - - fun asString(): String = _value().asStringOrThrow() - } - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParams.kt index 9575b9fa..e6ef1cd1 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParams.kt @@ -3,104 +3,166 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Default endpoint. Simply replies with 'Hello, World!'. Authorization is not required */ class TopLevelHelloWorldParams -constructor( - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { +private constructor( + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams - fun _additionalQueryParams(): Map> = additionalQueryParams + override fun _headers(): Headers = additionalHeaders - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is TopLevelHelloWorldParams && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash(additionalQueryParams, additionalHeaders) - } - - override fun toString() = - "TopLevelHelloWorldParams{additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + override fun _queryParams(): QueryParams = additionalQueryParams fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): TopLevelHelloWorldParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [TopLevelHelloWorldParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [TopLevelHelloWorldParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(topLevelHelloWorldParams: TopLevelHelloWorldParams) = apply { - additionalQueryParams(topLevelHelloWorldParams.additionalQueryParams) - additionalHeaders(topLevelHelloWorldParams.additionalHeaders) + additionalHeaders = topLevelHelloWorldParams.additionalHeaders.toBuilder() + additionalQueryParams = topLevelHelloWorldParams.additionalQueryParams.toBuilder() } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [TopLevelHelloWorldParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): TopLevelHelloWorldParams = - TopLevelHelloWorldParams( - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable() - ) + TopLevelHelloWorldParams(additionalHeaders.build(), additionalQueryParams.build()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is TopLevelHelloWorldParams && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "TopLevelHelloWorldParams{additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/User.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/User.kt index c254ff9d..ac80f854 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/User.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/User.kt @@ -7,215 +7,329 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = User.Builder::class) @NoAutoDetect class User +@JsonCreator private constructor( - private val id: JsonField, - private val givenName: JsonField, - private val familyName: JsonField, - private val email: JsonField, - private val avatarUrl: JsonField, - private val created: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("avatar_url") + @ExcludeMissing + private val avatarUrl: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing private val email: JsonField = JsonMissing.of(), + @JsonProperty("family_name") + @ExcludeMissing + private val familyName: JsonField = JsonMissing.of(), + @JsonProperty("given_name") + @ExcludeMissing + private val givenName: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the user */ + /** + * Unique identifier for the user + * + * @throws BraintrustInvalidDataException 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") - /** Given name of the user */ - fun givenName(): Optional = Optional.ofNullable(givenName.getNullable("given_name")) - - /** Family name of the user */ - fun familyName(): Optional = Optional.ofNullable(familyName.getNullable("family_name")) - - /** The user's email */ - fun email(): Optional = Optional.ofNullable(email.getNullable("email")) - - /** URL of the user's Avatar image */ + /** + * URL of the user's Avatar image + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun avatarUrl(): Optional = Optional.ofNullable(avatarUrl.getNullable("avatar_url")) - /** Date of user creation */ + /** + * Date of user creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** Unique identifier for the user */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** Given name of the user */ - @JsonProperty("given_name") @ExcludeMissing fun _givenName() = givenName - - /** Family name of the user */ - @JsonProperty("family_name") @ExcludeMissing fun _familyName() = familyName + /** + * The user's email + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = Optional.ofNullable(email.getNullable("email")) - /** The user's email */ - @JsonProperty("email") @ExcludeMissing fun _email() = email + /** + * Family name of the user + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun familyName(): Optional = Optional.ofNullable(familyName.getNullable("family_name")) - /** URL of the user's Avatar image */ - @JsonProperty("avatar_url") @ExcludeMissing fun _avatarUrl() = avatarUrl + /** + * Given name of the user + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun givenName(): Optional = Optional.ofNullable(givenName.getNullable("given_name")) - /** Date of user creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created + /** + * 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 [avatarUrl]. + * + * Unlike [avatarUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("avatar_url") @ExcludeMissing fun _avatarUrl(): JsonField = avatarUrl + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [familyName]. + * + * Unlike [familyName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("family_name") @ExcludeMissing fun _familyName(): JsonField = familyName + + /** + * Returns the raw JSON value of [givenName]. + * + * Unlike [givenName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("given_name") @ExcludeMissing fun _givenName(): JsonField = givenName @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): User = apply { - if (!validated) { - id() - givenName() - familyName() - email() - avatarUrl() - created() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): User = apply { + if (validated) { + return@apply } - return other is User && - this.id == other.id && - this.givenName == other.givenName && - this.familyName == other.familyName && - this.email == other.email && - this.avatarUrl == other.avatarUrl && - this.created == other.created && - this.additionalProperties == other.additionalProperties + id() + avatarUrl() + created() + email() + familyName() + givenName() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - givenName, - familyName, - email, - avatarUrl, - created, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "User{id=$id, givenName=$givenName, familyName=$familyName, email=$email, avatarUrl=$avatarUrl, created=$created, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [User]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [User]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var givenName: JsonField = JsonMissing.of() - private var familyName: JsonField = JsonMissing.of() - private var email: JsonField = JsonMissing.of() + private var id: JsonField? = null private var avatarUrl: JsonField = JsonMissing.of() private var created: JsonField = JsonMissing.of() + private var email: JsonField = JsonMissing.of() + private var familyName: JsonField = JsonMissing.of() + private var givenName: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(user: User) = apply { - this.id = user.id - this.givenName = user.givenName - this.familyName = user.familyName - this.email = user.email - this.avatarUrl = user.avatarUrl - this.created = user.created - additionalProperties(user.additionalProperties) + id = user.id + avatarUrl = user.avatarUrl + created = user.created + email = user.email + familyName = user.familyName + givenName = user.givenName + additionalProperties = user.additionalProperties.toMutableMap() } /** Unique identifier for the user */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the user */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = id } - - /** Given name of the user */ - fun givenName(givenName: String) = givenName(JsonField.of(givenName)) + /** + * 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 } - /** Given name of the user */ - @JsonProperty("given_name") - @ExcludeMissing - fun givenName(givenName: JsonField) = apply { this.givenName = givenName } - - /** Family name of the user */ - fun familyName(familyName: String) = familyName(JsonField.of(familyName)) - - /** Family name of the user */ - @JsonProperty("family_name") - @ExcludeMissing - fun familyName(familyName: JsonField) = apply { this.familyName = familyName } + /** URL of the user's Avatar image */ + fun avatarUrl(avatarUrl: String?) = avatarUrl(JsonField.ofNullable(avatarUrl)) + + /** Alias for calling [Builder.avatarUrl] with `avatarUrl.orElse(null)`. */ + fun avatarUrl(avatarUrl: Optional) = avatarUrl(avatarUrl.getOrNull()) + + /** + * Sets [Builder.avatarUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.avatarUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun avatarUrl(avatarUrl: JsonField) = apply { this.avatarUrl = avatarUrl } - /** The user's email */ - fun email(email: String) = email(JsonField.of(email)) + /** Date of user creation */ + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } /** The user's email */ - @JsonProperty("email") - @ExcludeMissing - fun email(email: JsonField) = apply { this.email = email } + fun email(email: String?) = email(JsonField.ofNullable(email)) - /** URL of the user's Avatar image */ - fun avatarUrl(avatarUrl: String) = avatarUrl(JsonField.of(avatarUrl)) + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) - /** URL of the user's Avatar image */ - @JsonProperty("avatar_url") - @ExcludeMissing - fun avatarUrl(avatarUrl: JsonField) = apply { this.avatarUrl = avatarUrl } + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { this.email = email } - /** Date of user creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) + /** Family name of the user */ + fun familyName(familyName: String?) = familyName(JsonField.ofNullable(familyName)) + + /** Alias for calling [Builder.familyName] with `familyName.orElse(null)`. */ + fun familyName(familyName: Optional) = familyName(familyName.getOrNull()) + + /** + * Sets [Builder.familyName] to an arbitrary JSON value. + * + * You should usually call [Builder.familyName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun familyName(familyName: JsonField) = apply { this.familyName = familyName } - /** Date of user creation */ - @JsonProperty("created") - @ExcludeMissing - fun created(created: JsonField) = apply { this.created = created } + /** Given name of the user */ + fun givenName(givenName: String?) = givenName(JsonField.ofNullable(givenName)) + + /** Alias for calling [Builder.givenName] with `givenName.orElse(null)`. */ + fun givenName(givenName: Optional) = givenName(givenName.getOrNull()) + + /** + * Sets [Builder.givenName] to an arbitrary JSON value. + * + * You should usually call [Builder.givenName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun givenName(givenName: JsonField) = apply { this.givenName = givenName } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [User]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): User = User( - id, - givenName, - familyName, - email, + checkRequired("id", id), avatarUrl, created, - additionalProperties.toUnmodifiable(), + email, + familyName, + givenName, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is User && id == other.id && avatarUrl == other.avatarUrl && created == other.created && email == other.email && familyName == other.familyName && givenName == other.givenName && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, avatarUrl, created, email, familyName, givenName, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "User{id=$id, avatarUrl=$avatarUrl, created=$created, email=$email, familyName=$familyName, givenName=$givenName, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPage.kt index 75c893f9..c1feb5eb 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.UserService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all users. The users are sorted by creation date, with the most recently-created users + * coming first + */ class UserListPage private constructor( private val usersService: UserService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is UserListPage && - this.usersService == other.usersService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is UserListPage && usersService == other.usersService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - usersService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(usersService, params, response) /* spotless:on */ override fun toString() = "UserListPage{usersService=$usersService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(usersService: UserService, params: UserListParams, response: Response) = - UserListPage( - usersService, - params, - response, - ) + UserListPage(usersService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "UserListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [UserListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: UserListPage, - ) : Iterable { + class AutoPager(private val firstPage: UserListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPageAsync.kt index 330014eb..23c28a26 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.UserServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all users. The users are sorted by creation date, with the most recently-created users + * coming first + */ class UserListPageAsync private constructor( private val usersService: UserServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is UserListPageAsync && - this.usersService == other.usersService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is UserListPageAsync && usersService == other.usersService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - usersService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(usersService, params, response) /* spotless:on */ override fun toString() = "UserListPageAsync{usersService=$usersService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(usersService: UserServiceAsync, params: UserListParams, response: Response) = - UserListPageAsync( - usersService, - params, - response, - ) + UserListPageAsync(usersService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "UserListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [UserListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: UserListPageAsync, - ) { + class AutoPager(private val firstPage: UserListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (User) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListParams.kt index 48836250..55618ca7 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserListParams.kt @@ -6,10 +6,11 @@ import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -19,9 +20,14 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all users. The users are sorted by creation date, with the most recently-created users + * coming first + */ class UserListParams -constructor( +private constructor( private val email: Email?, private val endingBefore: String?, private val familyName: FamilyName?, @@ -30,92 +36,132 @@ constructor( private val limit: Long?, private val orgName: String?, private val startingAfter: String?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { - + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Email of the user to search for. You may pass the param multiple times to filter for more + * than one email + */ fun email(): Optional = Optional.ofNullable(email) + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Family name of the user to search for. You may pass the param multiple times to filter for + * more than one family name + */ fun familyName(): Optional = Optional.ofNullable(familyName) + /** + * Given name of the user to search for. You may pass the param multiple times to filter for + * more than one given name + */ fun givenName(): Optional = Optional.ofNullable(givenName) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** Filter search results to within a particular organization */ fun orgName(): Optional = Optional.ofNullable(orgName) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.email?.let { params.put("email", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.familyName?.let { params.put("family_name", listOf(it.toString())) } - this.givenName?.let { params.put("given_name", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.orgName?.let { params.put("org_name", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is UserListParams && - this.email == other.email && - this.endingBefore == other.endingBefore && - this.familyName == other.familyName && - this.givenName == other.givenName && - this.ids == other.ids && - this.limit == other.limit && - this.orgName == other.orgName && - this.startingAfter == other.startingAfter && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - email, - endingBefore, - familyName, - givenName, - ids, - limit, - orgName, - startingAfter, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "UserListParams{email=$email, endingBefore=$endingBefore, familyName=$familyName, givenName=$givenName, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + email?.accept( + object : Email.Visitor { + override fun visitString(string: String) { + put("email", string) + } + + override fun visitStrings(strings: List) { + put("email", strings.joinToString(",")) + } + } + ) + endingBefore?.let { put("ending_before", it) } + familyName?.accept( + object : FamilyName.Visitor { + override fun visitString(string: String) { + put("family_name", string) + } + + override fun visitStrings(strings: List) { + put("family_name", strings.joinToString(",")) + } + } + ) + givenName?.accept( + object : GivenName.Visitor { + override fun visitString(string: String) { + put("given_name", string) + } + + override fun visitStrings(strings: List) { + put("given_name", strings.joinToString(",")) + } + } + ) + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + orgName?.let { put("org_name", it) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + @JvmStatic fun none(): UserListParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [UserListParams]. */ @JvmStatic fun builder() = Builder() } + /** A builder for [UserListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var email: Email? = null private var endingBefore: String? = null @@ -125,40 +171,37 @@ constructor( private var limit: Long? = null private var orgName: String? = null private var startingAfter: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(userListParams: UserListParams) = apply { - this.email = userListParams.email - this.endingBefore = userListParams.endingBefore - this.familyName = userListParams.familyName - this.givenName = userListParams.givenName - this.ids = userListParams.ids - this.limit = userListParams.limit - this.orgName = userListParams.orgName - this.startingAfter = userListParams.startingAfter - additionalQueryParams(userListParams.additionalQueryParams) - additionalHeaders(userListParams.additionalHeaders) + email = userListParams.email + endingBefore = userListParams.endingBefore + familyName = userListParams.familyName + givenName = userListParams.givenName + ids = userListParams.ids + limit = userListParams.limit + orgName = userListParams.orgName + startingAfter = userListParams.startingAfter + additionalHeaders = userListParams.additionalHeaders.toBuilder() + additionalQueryParams = userListParams.additionalQueryParams.toBuilder() } /** * Email of the user to search for. You may pass the param multiple times to filter for more * than one email */ - fun email(email: Email) = apply { this.email = email } + fun email(email: Email?) = apply { this.email = email } - /** - * Email of the user to search for. You may pass the param multiple times to filter for more - * than one email - */ - fun email(string: String) = apply { this.email = Email.ofString(string) } + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) - /** - * Email of the user to search for. You may pass the param multiple times to filter for more - * than one email - */ - fun email(strings: List) = apply { this.email = Email.ofStrings(strings) } + /** Alias for calling [email] with `Email.ofString(string)`. */ + fun email(string: String) = email(Email.ofString(string)) + + /** Alias for calling [email] with `Email.ofStrings(strings)`. */ + fun emailOfStrings(strings: List) = email(Email.ofStrings(strings)) /** * Pagination cursor id. @@ -167,71 +210,74 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Family name of the user to search for. You may pass the param multiple times to filter - * for more than one family name - */ - fun familyName(familyName: FamilyName) = apply { this.familyName = familyName } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Family name of the user to search for. You may pass the param multiple times to filter * for more than one family name */ - fun familyName(string: String) = apply { this.familyName = FamilyName.ofString(string) } + fun familyName(familyName: FamilyName?) = apply { this.familyName = familyName } - /** - * Family name of the user to search for. You may pass the param multiple times to filter - * for more than one family name - */ - fun familyName(strings: List) = apply { - this.familyName = FamilyName.ofStrings(strings) - } + /** Alias for calling [Builder.familyName] with `familyName.orElse(null)`. */ + fun familyName(familyName: Optional) = familyName(familyName.getOrNull()) - /** - * Given name of the user to search for. You may pass the param multiple times to filter for - * more than one given name - */ - fun givenName(givenName: GivenName) = apply { this.givenName = givenName } + /** Alias for calling [familyName] with `FamilyName.ofString(string)`. */ + fun familyName(string: String) = familyName(FamilyName.ofString(string)) - /** - * Given name of the user to search for. You may pass the param multiple times to filter for - * more than one given name - */ - fun givenName(string: String) = apply { this.givenName = GivenName.ofString(string) } + /** Alias for calling [familyName] with `FamilyName.ofStrings(strings)`. */ + fun familyNameOfStrings(strings: List) = familyName(FamilyName.ofStrings(strings)) /** * Given name of the user to search for. You may pass the param multiple times to filter for * more than one given name */ - fun givenName(strings: List) = apply { - this.givenName = GivenName.ofStrings(strings) - } + fun givenName(givenName: GivenName?) = apply { this.givenName = givenName } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.givenName] with `givenName.orElse(null)`. */ + fun givenName(givenName: Optional) = givenName(givenName.getOrNull()) + + /** Alias for calling [givenName] with `GivenName.ofString(string)`. */ + fun givenName(string: String) = givenName(GivenName.ofString(string)) + + /** Alias for calling [givenName] with `GivenName.ofStrings(strings)`. */ + fun givenNameOfStrings(strings: List) = givenName(GivenName.ofStrings(strings)) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** Filter search results to within a particular organization */ - fun orgName(orgName: String) = apply { this.orgName = orgName } + fun orgName(orgName: String?) = apply { this.orgName = orgName } + + /** Alias for calling [Builder.orgName] with `orgName.orElse(null)`. */ + fun orgName(orgName: Optional) = orgName(orgName.getOrNull()) /** * Pagination cursor id. @@ -240,48 +286,115 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [UserListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): UserListParams = UserListParams( email, @@ -292,11 +405,15 @@ constructor( limit, orgName, startingAfter, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + /** + * Email of the user to search for. You may pass the param multiple times to filter for more + * than one email + */ @JsonDeserialize(using = Email.Deserializer::class) @JsonSerialize(using = Email.Serializer::class) class Email @@ -306,8 +423,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -330,35 +445,23 @@ constructor( } } - fun validate(): Email = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Email: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Email && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Email && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Email{string=$string}" strings != null -> "Email{strings=$strings}" _json != null -> "Email{_unknown=$_json}" else -> throw IllegalStateException("Invalid Email") } - } companion object { @@ -367,21 +470,33 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Email(strings = strings) } + /** An interface that defines how to map each variant of [Email] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Email] to a value of type [T]. + * + * An instance of [Email] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Email: $json") } } - class Deserializer : BaseDeserializer(Email::class) { + internal class Deserializer : BaseDeserializer(Email::class) { override fun ObjectCodec.deserialize(node: JsonNode): Email { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Email(string = it, _json = json) } @@ -393,12 +508,12 @@ constructor( } } - class Serializer : BaseSerializer(Email::class) { + internal class Serializer : BaseSerializer(Email::class) { override fun serialize( value: Email, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -410,6 +525,10 @@ constructor( } } + /** + * Family name of the user to search for. You may pass the param multiple times to filter for + * more than one family name + */ @JsonDeserialize(using = FamilyName.Deserializer::class) @JsonSerialize(using = FamilyName.Serializer::class) class FamilyName @@ -419,8 +538,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -443,37 +560,23 @@ constructor( } } - fun validate(): FamilyName = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown FamilyName: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is FamilyName && - this.string == other.string && - this.strings == other.strings + return /* spotless:off */ other is FamilyName && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "FamilyName{string=$string}" strings != null -> "FamilyName{strings=$strings}" _json != null -> "FamilyName{_unknown=$_json}" else -> throw IllegalStateException("Invalid FamilyName") } - } companion object { @@ -482,21 +585,35 @@ constructor( @JvmStatic fun ofStrings(strings: List) = FamilyName(strings = strings) } + /** + * An interface that defines how to map each variant of [FamilyName] to a value of type [T]. + */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [FamilyName] to a value of type [T]. + * + * An instance of [FamilyName] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown FamilyName: $json") } } - class Deserializer : BaseDeserializer(FamilyName::class) { + internal class Deserializer : BaseDeserializer(FamilyName::class) { override fun ObjectCodec.deserialize(node: JsonNode): FamilyName { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return FamilyName(string = it, _json = json) } @@ -508,12 +625,12 @@ constructor( } } - class Serializer : BaseSerializer(FamilyName::class) { + internal class Serializer : BaseSerializer(FamilyName::class) { override fun serialize( value: FamilyName, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -525,6 +642,10 @@ constructor( } } + /** + * Given name of the user to search for. You may pass the param multiple times to filter for + * more than one given name + */ @JsonDeserialize(using = GivenName.Deserializer::class) @JsonSerialize(using = GivenName.Serializer::class) class GivenName @@ -534,8 +655,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -558,37 +677,23 @@ constructor( } } - fun validate(): GivenName = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown GivenName: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is GivenName && - this.string == other.string && - this.strings == other.strings + return /* spotless:off */ other is GivenName && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "GivenName{string=$string}" strings != null -> "GivenName{strings=$strings}" _json != null -> "GivenName{_unknown=$_json}" else -> throw IllegalStateException("Invalid GivenName") } - } companion object { @@ -597,21 +702,35 @@ constructor( @JvmStatic fun ofStrings(strings: List) = GivenName(strings = strings) } + /** + * An interface that defines how to map each variant of [GivenName] to a value of type [T]. + */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [GivenName] to a value of type [T]. + * + * An instance of [GivenName] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown GivenName: $json") } } - class Deserializer : BaseDeserializer(GivenName::class) { + internal class Deserializer : BaseDeserializer(GivenName::class) { override fun ObjectCodec.deserialize(node: JsonNode): GivenName { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return GivenName(string = it, _json = json) } @@ -623,12 +742,12 @@ constructor( } } - class Serializer : BaseSerializer(GivenName::class) { + internal class Serializer : BaseSerializer(GivenName::class) { override fun serialize( value: GivenName, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -640,6 +759,10 @@ constructor( } } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -649,8 +772,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -673,35 +794,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -710,21 +819,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -736,12 +856,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -752,4 +872,17 @@ constructor( } } } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is UserListParams && email == other.email && endingBefore == other.endingBefore && familyName == other.familyName && givenName == other.givenName && ids == other.ids && limit == other.limit && orgName == other.orgName && startingAfter == other.startingAfter && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(email, endingBefore, familyName, givenName, ids, limit, orgName, startingAfter, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "UserListParams{email=$email, endingBefore=$endingBefore, familyName=$familyName, givenName=$givenName, ids=$ids, limit=$limit, orgName=$orgName, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserRetrieveParams.kt index 5dfac4ef..4d668314 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/UserRetrieveParams.kt @@ -3,22 +3,30 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a user object by its id */ class UserRetrieveParams -constructor( +private constructor( private val userId: String, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** User id */ fun userId(): String = userId - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -27,101 +35,167 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is UserRetrieveParams && - this.userId == other.userId && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - userId, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "UserRetrieveParams{userId=$userId, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [UserRetrieveParams]. + * + * The following fields are required: + * ```java + * .userId() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [UserRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var userId: String? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(userRetrieveParams: UserRetrieveParams) = apply { - this.userId = userRetrieveParams.userId - additionalQueryParams(userRetrieveParams.additionalQueryParams) - additionalHeaders(userRetrieveParams.additionalHeaders) + userId = userRetrieveParams.userId + additionalHeaders = userRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = userRetrieveParams.additionalQueryParams.toBuilder() } /** User id */ fun userId(userId: String) = apply { this.userId = userId } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(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 putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + 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 putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + 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 [UserRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .userId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): UserRetrieveParams = UserRetrieveParams( - checkNotNull(userId) { "`userId` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), + checkRequired("userId", userId), + additionalHeaders.build(), + additionalQueryParams.build(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is UserRetrieveParams && userId == other.userId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(userId, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "UserRetrieveParams{userId=$userId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/View.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/View.kt index 84463eb2..f7439666 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/View.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/View.kt @@ -8,506 +8,636 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = View.Builder::class) @NoAutoDetect class View +@JsonCreator private constructor( - private val id: JsonField, - private val objectType: JsonField, - private val objectId: JsonField, - private val viewType: JsonField, - private val name: JsonField, - private val created: JsonField, - private val viewData: JsonField, - private val options: JsonField, - private val userId: JsonField, - private val deletedAt: JsonField, - private val additionalProperties: Map, + @JsonProperty("id") @ExcludeMissing private val id: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("view_type") + @ExcludeMissing + private val viewType: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + private val created: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("options") + @ExcludeMissing + private val options: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("view_data") + @ExcludeMissing + private val viewData: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - /** Unique identifier for the view */ + /** + * Unique identifier for the view + * + * @throws BraintrustInvalidDataException 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 object type that the ACL applies to */ - fun objectType(): ObjectType = objectType.getRequired("object_type") + /** + * Name of the view + * + * @throws BraintrustInvalidDataException 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") - /** The id of the object the view applies to */ + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") - /** Type of table that the view corresponds to. */ + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun viewType(): Optional = Optional.ofNullable(viewType.getNullable("view_type")) - /** Name of the view */ - fun name(): String = name.getRequired("name") - - /** Date of view creation */ + /** + * Date of view creation + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun created(): Optional = Optional.ofNullable(created.getNullable("created")) - /** The view definition */ - fun viewData(): Optional = Optional.ofNullable(viewData.getNullable("view_data")) - - /** Options for the view in the app */ - fun options(): Optional = Optional.ofNullable(options.getNullable("options")) - - /** Identifies the user who created the view */ - fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - - /** Date of role deletion, or null if the role is still active */ + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun deletedAt(): Optional = Optional.ofNullable(deletedAt.getNullable("deleted_at")) - /** Unique identifier for the view */ - @JsonProperty("id") @ExcludeMissing fun _id() = id - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") @ExcludeMissing fun _objectType() = objectType - - /** The id of the object the view applies to */ - @JsonProperty("object_id") @ExcludeMissing fun _objectId() = objectId - - /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") @ExcludeMissing fun _viewType() = viewType - - /** Name of the view */ - @JsonProperty("name") @ExcludeMissing fun _name() = name - - /** Date of view creation */ - @JsonProperty("created") @ExcludeMissing fun _created() = created - - /** The view definition */ - @JsonProperty("view_data") @ExcludeMissing fun _viewData() = viewData + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = Optional.ofNullable(options.getNullable("options")) - /** Options for the view in the app */ - @JsonProperty("options") @ExcludeMissing fun _options() = options + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) - /** Identifies the user who created the view */ - @JsonProperty("user_id") @ExcludeMissing fun _userId() = userId + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewData(): Optional = Optional.ofNullable(viewData.getNullable("view_data")) - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") @ExcludeMissing fun _deletedAt() = deletedAt + /** + * 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 [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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_type") @ExcludeMissing fun _viewType(): JsonField = viewType + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_data") @ExcludeMissing fun _viewData(): JsonField = viewData @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): View = apply { - if (!validated) { - id() - objectType() - objectId() - viewType() - name() - created() - viewData().map { it.validate() } - options().map { it.validate() } - userId() - deletedAt() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): View = apply { + if (validated) { + return@apply } - return other is View && - this.id == other.id && - this.objectType == other.objectType && - this.objectId == other.objectId && - this.viewType == other.viewType && - this.name == other.name && - this.created == other.created && - this.viewData == other.viewData && - this.options == other.options && - this.userId == other.userId && - this.deletedAt == other.deletedAt && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - id, - objectType, - objectId, - viewType, - name, - created, - viewData, - options, - userId, - deletedAt, - additionalProperties, - ) - } - return hashCode + id() + name() + objectId() + objectType() + viewType() + created() + deletedAt() + options().ifPresent { it.validate() } + userId() + viewData().ifPresent { it.validate() } + validated = true } - override fun toString() = - "View{id=$id, objectType=$objectType, objectId=$objectId, viewType=$viewType, name=$name, created=$created, viewData=$viewData, options=$options, userId=$userId, deletedAt=$deletedAt, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [View]. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [View]. */ + class Builder internal constructor() { - private var id: JsonField = JsonMissing.of() - private var objectType: JsonField = JsonMissing.of() - private var objectId: JsonField = JsonMissing.of() - private var viewType: JsonField = JsonMissing.of() - private var name: JsonField = JsonMissing.of() + private var id: JsonField? = null + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var viewType: JsonField? = null private var created: JsonField = JsonMissing.of() - private var viewData: JsonField = JsonMissing.of() + private var deletedAt: JsonField = JsonMissing.of() private var options: JsonField = JsonMissing.of() private var userId: JsonField = JsonMissing.of() - private var deletedAt: JsonField = JsonMissing.of() + private var viewData: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(view: View) = apply { - this.id = view.id - this.objectType = view.objectType - this.objectId = view.objectId - this.viewType = view.viewType - this.name = view.name - this.created = view.created - this.viewData = view.viewData - this.options = view.options - this.userId = view.userId - this.deletedAt = view.deletedAt - additionalProperties(view.additionalProperties) + id = view.id + name = view.name + objectId = view.objectId + objectType = view.objectType + viewType = view.viewType + created = view.created + deletedAt = view.deletedAt + options = view.options + userId = view.userId + viewData = view.viewData + additionalProperties = view.additionalProperties.toMutableMap() } /** Unique identifier for the view */ fun id(id: String) = id(JsonField.of(id)) - /** Unique identifier for the view */ - @JsonProperty("id") @ExcludeMissing fun id(id: JsonField) = apply { this.id = 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 } - /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = objectType(JsonField.of(objectType)) + /** Name of the view */ + fun name(name: String) = name(JsonField.of(name)) - /** The object type that the ACL applies to */ - @JsonProperty("object_type") - @ExcludeMissing - fun objectType(objectType: JsonField) = apply { this.objectType = objectType } + /** + * 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 } /** The id of the object the view applies to */ fun objectId(objectId: String) = objectId(JsonField.of(objectId)) - /** The id of the object the view applies to */ - @JsonProperty("object_id") - @ExcludeMissing + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ fun objectId(objectId: JsonField) = apply { this.objectId = objectId } - /** Type of table that the view corresponds to. */ - fun viewType(viewType: ViewType) = viewType(JsonField.of(viewType)) + /** The object type that the ACL applies to */ + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") - @ExcludeMissing + fun viewType(viewType: ViewType?) = viewType(JsonField.ofNullable(viewType)) + + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) + + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun viewType(viewType: JsonField) = apply { this.viewType = viewType } - /** Name of the view */ - fun name(name: String) = name(JsonField.of(name)) - - /** Name of the view */ - @JsonProperty("name") - @ExcludeMissing - fun name(name: JsonField) = apply { this.name = name } - - /** Date of view creation */ - fun created(created: OffsetDateTime) = created(JsonField.of(created)) - /** Date of view creation */ - @JsonProperty("created") - @ExcludeMissing + fun created(created: OffsetDateTime?) = created(JsonField.ofNullable(created)) + + /** Alias for calling [Builder.created] with `created.orElse(null)`. */ + fun created(created: Optional) = created(created.getOrNull()) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun created(created: JsonField) = apply { this.created = created } - /** The view definition */ - fun viewData(viewData: ViewData) = viewData(JsonField.of(viewData)) - - /** The view definition */ - @JsonProperty("view_data") - @ExcludeMissing - fun viewData(viewData: JsonField) = apply { this.viewData = viewData } - - /** Options for the view in the app */ - fun options(options: ViewOptions) = options(JsonField.of(options)) + /** Date of role deletion, or null if the role is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } /** Options for the view in the app */ - @JsonProperty("options") - @ExcludeMissing + fun options(options: ViewOptions?) = options(JsonField.ofNullable(options)) + + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ fun options(options: JsonField) = apply { this.options = options } /** Identifies the user who created the view */ - fun userId(userId: String) = userId(JsonField.of(userId)) + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) - /** Identifies the user who created the view */ - @JsonProperty("user_id") - @ExcludeMissing - fun userId(userId: JsonField) = apply { this.userId = userId } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - /** Date of role deletion, or null if the role is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = deletedAt(JsonField.of(deletedAt)) + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") - @ExcludeMissing - fun deletedAt(deletedAt: JsonField) = apply { this.deletedAt = deletedAt } + /** The view definition */ + fun viewData(viewData: ViewData?) = viewData(JsonField.ofNullable(viewData)) + + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) + + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewData(viewData: JsonField) = apply { this.viewData = viewData } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [View]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ fun build(): View = View( - id, - objectType, - objectId, - viewType, - name, + checkRequired("id", id), + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + checkRequired("viewType", viewType), created, - viewData, + deletedAt, options, userId, - deletedAt, - additionalProperties.toUnmodifiable(), + viewData, + additionalProperties.toImmutable(), ) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - + /** Type of table that the view corresponds to. */ + class ViewType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - companion object { - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + @JvmField val PROJECTS = of("projects") - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + @JvmField val EXPERIMENTS = of("experiments") - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + @JvmField val EXPERIMENT = of("experiment") - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + @JvmField val PLAYGROUNDS = of("playgrounds") - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + @JvmField val PLAYGROUND = of("playground") - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + @JvmField val DATASETS = of("datasets") - @JvmField val GROUP = ObjectType(JsonField.of("group")) + @JvmField val DATASET = of("dataset") - @JvmField val ROLE = ObjectType(JsonField.of("role")) + @JvmField val PROMPTS = of("prompts") - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + @JvmField val TOOLS = of("tools") - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + @JvmField val SCORERS = of("scorers") - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + @JvmField val LOGS = of("logs") - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) } + /** An enum containing [ViewType]'s known values. */ enum class Known { - ORGANIZATION, - PROJECT, + PROJECTS, + EXPERIMENTS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + PROMPTS, + TOOLS, + SCORERS, + LOGS, } + /** + * An enum containing [ViewType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ViewType] 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 { - ORGANIZATION, - PROJECT, + PROJECTS, + EXPERIMENTS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + /** An enum member indicating that [ViewType] 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) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT + PROJECTS -> Value.PROJECTS + EXPERIMENTS -> Value.EXPERIMENTS EXPERIMENT -> Value.EXPERIMENT + PLAYGROUNDS -> Value.PLAYGROUNDS + PLAYGROUND -> Value.PLAYGROUND + DATASETS -> Value.DATASETS DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT + PROMPTS -> Value.PROMPTS + TOOLS -> Value.TOOLS + SCORERS -> Value.SCORERS + LOGS -> Value.LOGS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT + PROJECTS -> Known.PROJECTS + EXPERIMENTS -> Known.EXPERIMENTS EXPERIMENT -> Known.EXPERIMENT + PLAYGROUNDS -> Known.PLAYGROUNDS + PLAYGROUND -> Known.PLAYGROUND + DATASETS -> Known.DATASETS DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") + PROMPTS -> Known.PROMPTS + TOOLS -> Known.TOOLS + SCORERS -> Known.SCORERS + LOGS -> Known.LOGS + else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") } - fun asString(): String = _value().asStringOrThrow() - } - - class ViewType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is ViewType && this.value == other.value + return /* spotless:off */ other is ViewType && value == other.value /* spotless:on */ } override fun hashCode() = value.hashCode() override fun toString() = value.toString() + } - companion object { - - @JvmField val PROJECTS = ViewType(JsonField.of("projects")) - - @JvmField val LOGS = ViewType(JsonField.of("logs")) - - @JvmField val EXPERIMENTS = ViewType(JsonField.of("experiments")) - - @JvmField val DATASETS = ViewType(JsonField.of("datasets")) - - @JvmField val PROMPTS = ViewType(JsonField.of("prompts")) - - @JvmField val PLAYGROUNDS = ViewType(JsonField.of("playgrounds")) - - @JvmField val EXPERIMENT = ViewType(JsonField.of("experiment")) - - @JvmField val DATASET = ViewType(JsonField.of("dataset")) - - @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) - } - - enum class Known { - PROJECTS, - LOGS, - EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, - EXPERIMENT, - DATASET, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - enum class Value { - PROJECTS, - LOGS, - EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, - EXPERIMENT, - DATASET, - _UNKNOWN, - } + return /* spotless:off */ other is View && id == other.id && name == other.name && objectId == other.objectId && objectType == other.objectType && viewType == other.viewType && created == other.created && deletedAt == other.deletedAt && options == other.options && userId == other.userId && viewData == other.viewData && additionalProperties == other.additionalProperties /* spotless:on */ + } - fun value(): Value = - when (this) { - PROJECTS -> Value.PROJECTS - LOGS -> Value.LOGS - EXPERIMENTS -> Value.EXPERIMENTS - DATASETS -> Value.DATASETS - PROMPTS -> Value.PROMPTS - PLAYGROUNDS -> Value.PLAYGROUNDS - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - else -> Value._UNKNOWN - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(id, name, objectId, objectType, viewType, created, deletedAt, options, userId, viewData, additionalProperties) } + /* spotless:on */ - fun known(): Known = - when (this) { - PROJECTS -> Known.PROJECTS - LOGS -> Known.LOGS - EXPERIMENTS -> Known.EXPERIMENTS - DATASETS -> Known.DATASETS - PROMPTS -> Known.PROMPTS - PLAYGROUNDS -> Known.PLAYGROUNDS - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") - } + override fun hashCode(): Int = hashCode - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "View{id=$id, name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, created=$created, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewCreateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewCreateParams.kt index 25b8ec2f..da386fa5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewCreateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewCreateParams.kt @@ -5,620 +5,1014 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create a new view. If there is an existing view with the same name as the one specified in the + * request, will return the existing view unmodified + */ class ViewCreateParams -constructor( - private val name: String, - private val objectId: String, - private val objectType: ObjectType, - private val viewType: ViewType?, - private val deletedAt: OffsetDateTime?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun viewType(): Optional = Optional.ofNullable(viewType) - - fun deletedAt(): Optional = Optional.ofNullable(deletedAt) - - fun options(): Optional = Optional.ofNullable(options) - - fun userId(): Optional = Optional.ofNullable(userId) - - fun viewData(): Optional = Optional.ofNullable(viewData) - - @JvmSynthetic - internal fun getBody(): ViewCreateBody { - return ViewCreateBody( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the view + * + * @throws BraintrustInvalidDataException 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() + + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewType(): Optional = body.viewType() + + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun deletedAt(): Optional = body.deletedAt() + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewData(): Optional = body.viewData() + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewType(): JsonField = body._viewType() + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _deletedAt(): JsonField = body._deletedAt() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewData(): JsonField = body._viewData() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ViewCreateBody.Builder::class) @NoAutoDetect - class ViewCreateBody - internal constructor( - private val name: String?, - private val objectId: String?, - private val objectType: ObjectType?, - private val viewType: ViewType?, - private val deletedAt: OffsetDateTime?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("view_type") + @ExcludeMissing + private val viewType: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("options") + @ExcludeMissing + private val options: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("view_data") + @ExcludeMissing + private val viewData: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the view */ - @JsonProperty("name") fun name(): String? = name - - /** The id of the object the view applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType - - /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") fun viewType(): ViewType? = viewType - - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") fun deletedAt(): OffsetDateTime? = deletedAt - - /** Options for the view in the app */ - @JsonProperty("options") fun options(): ViewOptions? = options - - /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(): String? = userId - - /** The view definition */ - @JsonProperty("view_data") fun viewData(): ViewData? = viewData + /** + * Name of the view + * + * @throws BraintrustInvalidDataException 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") + + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewType(): Optional = Optional.ofNullable(viewType.getNullable("view_type")) + + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun deletedAt(): Optional = + Optional.ofNullable(deletedAt.getNullable("deleted_at")) + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = Optional.ofNullable(options.getNullable("options")) + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewData(): Optional = Optional.ofNullable(viewData.getNullable("view_data")) + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_type") @ExcludeMissing fun _viewType(): JsonField = viewType + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_data") @ExcludeMissing fun _viewData(): JsonField = viewData @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ViewCreateBody && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.viewType == other.viewType && - this.deletedAt == other.deletedAt && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalProperties, - ) - } - return hashCode + name() + objectId() + objectType() + viewType() + deletedAt() + options().ifPresent { it.validate() } + userId() + viewData().ifPresent { it.validate() } + validated = true } - override fun toString() = - "ViewCreateBody{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalProperties=$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() + * .objectId() + * .objectType() + * .viewType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var viewType: ViewType? = null - private var deletedAt: OffsetDateTime? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var viewType: JsonField? = null + private var deletedAt: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() + private var viewData: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(viewCreateBody: ViewCreateBody) = apply { - this.name = viewCreateBody.name - this.objectId = viewCreateBody.objectId - this.objectType = viewCreateBody.objectType - this.viewType = viewCreateBody.viewType - this.deletedAt = viewCreateBody.deletedAt - this.options = viewCreateBody.options - this.userId = viewCreateBody.userId - this.viewData = viewCreateBody.viewData - additionalProperties(viewCreateBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + objectId = body.objectId + objectType = body.objectType + viewType = body.viewType + deletedAt = body.deletedAt + options = body.options + userId = body.userId + viewData = body.viewData + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the view */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** The id of the object the view applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = viewType(JsonField.ofNullable(viewType)) + + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) + + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewType(viewType: JsonField) = apply { this.viewType = viewType } /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") - fun deletedAt(deletedAt: OffsetDateTime) = apply { this.deletedAt = deletedAt } + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { + this.deletedAt = deletedAt + } /** Options for the view in the app */ - @JsonProperty("options") - fun options(options: ViewOptions) = apply { this.options = options } + fun options(options: ViewOptions?) = options(JsonField.ofNullable(options)) + + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } /** The view definition */ - @JsonProperty("view_data") - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + fun viewData(viewData: ViewData?) = viewData(JsonField.ofNullable(viewData)) + + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) + + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewData(viewData: JsonField) = apply { this.viewData = viewData } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ViewCreateBody = - ViewCreateBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - viewType, + 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() + * .objectId() + * .objectType() + * .viewType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + checkRequired("viewType", viewType), deletedAt, options, userId, viewData, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && objectId == other.objectId && objectType == other.objectType && viewType == other.viewType && deletedAt == other.deletedAt && options == other.options && userId == other.userId && viewData == other.viewData && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ViewCreateParams && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.viewType == other.viewType && - this.deletedAt == other.deletedAt && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, objectId, objectType, viewType, deletedAt, options, userId, viewData, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ViewCreateParams{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewCreateParams]. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewCreateParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var viewType: ViewType? = null - private var deletedAt: OffsetDateTime? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(viewCreateParams: ViewCreateParams) = apply { - this.name = viewCreateParams.name - this.objectId = viewCreateParams.objectId - this.objectType = viewCreateParams.objectType - this.viewType = viewCreateParams.viewType - this.deletedAt = viewCreateParams.deletedAt - this.options = viewCreateParams.options - this.userId = viewCreateParams.userId - this.viewData = viewCreateParams.viewData - additionalQueryParams(viewCreateParams.additionalQueryParams) - additionalHeaders(viewCreateParams.additionalHeaders) - additionalBodyProperties(viewCreateParams.additionalBodyProperties) + body = viewCreateParams.body.toBuilder() + additionalHeaders = viewCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = viewCreateParams.additionalQueryParams.toBuilder() } /** Name of the view */ - fun name(name: String) = apply { this.name = 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) } /** The id of the object the view applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** Type of table that the view corresponds to. */ - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = apply { body.viewType(viewType) } - /** Date of role deletion, or null if the role is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = apply { this.deletedAt = deletedAt } + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) - /** Options for the view in the app */ - fun options(options: ViewOptions) = apply { this.options = options } + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewType(viewType: JsonField) = apply { body.viewType(viewType) } - /** Identifies the user who created the view */ - fun userId(userId: String) = apply { this.userId = userId } + /** Date of role deletion, or null if the role is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = apply { body.deletedAt(deletedAt) } - /** The view definition */ - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { body.deletedAt(deletedAt) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } + /** Options for the view in the app */ + fun options(options: ViewOptions?) = apply { body.options(options) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun options(options: JsonField) = apply { body.options(options) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** Identifies the user who created the view */ + fun userId(userId: String?) = apply { body.userId(userId) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** The view definition */ + fun viewData(viewData: ViewData?) = apply { body.viewData(viewData) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewData(viewData: JsonField) = apply { body.viewData(viewData) } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.additionalProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + body.putAdditionalProperty(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.putAllAdditionalProperties(additionalBodyProperties) } - fun build(): ViewCreateParams = - ViewCreateParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - viewType, - deletedAt, - options, - userId, - viewData, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - return other is ObjectType && this.value == other.value + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - override fun hashCode() = value.hashCode() + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } - override fun toString() = value.toString() + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - companion object { + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - fun asString(): String = _value().asStringOrThrow() - } + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } - class ViewType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** + * Returns an immutable instance of [ViewCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewCreateParams = + ViewCreateParams(body.build(), additionalHeaders.build(), additionalQueryParams.build()) + } + /** Type of table that the view corresponds to. */ + class ViewType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ViewType && this.value == other.value - } + companion object { - override fun hashCode() = value.hashCode() + @JvmField val PROJECTS = of("projects") - override fun toString() = value.toString() + @JvmField val EXPERIMENTS = of("experiments") - companion object { + @JvmField val EXPERIMENT = of("experiment") - @JvmField val PROJECTS = ViewType(JsonField.of("projects")) + @JvmField val PLAYGROUNDS = of("playgrounds") - @JvmField val LOGS = ViewType(JsonField.of("logs")) + @JvmField val PLAYGROUND = of("playground") - @JvmField val EXPERIMENTS = ViewType(JsonField.of("experiments")) + @JvmField val DATASETS = of("datasets") - @JvmField val DATASETS = ViewType(JsonField.of("datasets")) + @JvmField val DATASET = of("dataset") - @JvmField val PROMPTS = ViewType(JsonField.of("prompts")) + @JvmField val PROMPTS = of("prompts") - @JvmField val PLAYGROUNDS = ViewType(JsonField.of("playgrounds")) + @JvmField val TOOLS = of("tools") - @JvmField val EXPERIMENT = ViewType(JsonField.of("experiment")) + @JvmField val SCORERS = of("scorers") - @JvmField val DATASET = ViewType(JsonField.of("dataset")) + @JvmField val LOGS = of("logs") @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) } + /** An enum containing [ViewType]'s known values. */ enum class Known { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, } + /** + * An enum containing [ViewType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ViewType] 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 { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + /** An enum member indicating that [ViewType] 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) { PROJECTS -> Value.PROJECTS - LOGS -> Value.LOGS EXPERIMENTS -> Value.EXPERIMENTS - DATASETS -> Value.DATASETS - PROMPTS -> Value.PROMPTS - PLAYGROUNDS -> Value.PLAYGROUNDS EXPERIMENT -> Value.EXPERIMENT + PLAYGROUNDS -> Value.PLAYGROUNDS + PLAYGROUND -> Value.PLAYGROUND + DATASETS -> Value.DATASETS DATASET -> Value.DATASET + PROMPTS -> Value.PROMPTS + TOOLS -> Value.TOOLS + SCORERS -> Value.SCORERS + LOGS -> Value.LOGS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { PROJECTS -> Known.PROJECTS - LOGS -> Known.LOGS EXPERIMENTS -> Known.EXPERIMENTS - DATASETS -> Known.DATASETS - PROMPTS -> Known.PROMPTS - PLAYGROUNDS -> Known.PLAYGROUNDS EXPERIMENT -> Known.EXPERIMENT + PLAYGROUNDS -> Known.PLAYGROUNDS + PLAYGROUND -> Known.PLAYGROUND + DATASETS -> Known.DATASETS DATASET -> Known.DATASET + PROMPTS -> Known.PROMPTS + TOOLS -> Known.TOOLS + SCORERS -> Known.SCORERS + LOGS -> Known.LOGS else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewCreateParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ViewCreateParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewData.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewData.kt index 1a019644..60697d88 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewData.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewData.kt @@ -7,99 +7,130 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** The view definition */ -@JsonDeserialize(builder = ViewData.Builder::class) @NoAutoDetect class ViewData +@JsonCreator private constructor( - private val search: JsonField, - private val additionalProperties: Map, + @JsonProperty("search") + @ExcludeMissing + private val search: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun search(): Optional = Optional.ofNullable(search.getNullable("search")) - @JsonProperty("search") @ExcludeMissing fun _search() = search + /** + * Returns the raw JSON value of [search]. + * + * Unlike [search], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("search") @ExcludeMissing fun _search(): JsonField = search @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ViewData = apply { - if (!validated) { - search().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ViewData = apply { + if (validated) { + return@apply } - return other is ViewData && - this.search == other.search && - this.additionalProperties == other.additionalProperties + search().ifPresent { it.validate() } + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(search, additionalProperties) - } - return hashCode - } - - override fun toString() = "ViewData{search=$search, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ViewData]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ViewData]. */ + class Builder internal constructor() { private var search: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(viewData: ViewData) = apply { - this.search = viewData.search - additionalProperties(viewData.additionalProperties) + search = viewData.search + additionalProperties = viewData.additionalProperties.toMutableMap() } - fun search(search: ViewDataSearch) = search(JsonField.of(search)) + fun search(search: ViewDataSearch?) = search(JsonField.ofNullable(search)) + + /** Alias for calling [Builder.search] with `search.orElse(null)`. */ + fun search(search: Optional) = search(search.getOrNull()) - @JsonProperty("search") - @ExcludeMissing + /** + * Sets [Builder.search] to an arbitrary JSON value. + * + * You should usually call [Builder.search] with a well-typed [ViewDataSearch] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun search(search: JsonField) = apply { this.search = search } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ViewData = ViewData(search, additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ViewData]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ViewData = ViewData(search, additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewData && search == other.search && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(search, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "ViewData{search=$search, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDataSearch.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDataSearch.kt index b64ebbc7..35428978 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDataSearch.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDataSearch.kt @@ -7,158 +7,291 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull -@JsonDeserialize(builder = ViewDataSearch.Builder::class) @NoAutoDetect class ViewDataSearch +@JsonCreator private constructor( - private val filter: JsonField>, - private val tag: JsonField>, - private val match: JsonField>, - private val sort: JsonField>, - private val additionalProperties: Map, + @JsonProperty("filter") + @ExcludeMissing + private val filter: JsonField> = JsonMissing.of(), + @JsonProperty("match") + @ExcludeMissing + private val match: JsonField> = JsonMissing.of(), + @JsonProperty("sort") + @ExcludeMissing + private val sort: JsonField> = JsonMissing.of(), + @JsonProperty("tag") + @ExcludeMissing + private val tag: JsonField> = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun filter(): Optional> = Optional.ofNullable(filter.getNullable("filter")) - fun tag(): Optional> = Optional.ofNullable(tag.getNullable("tag")) - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun match(): Optional> = Optional.ofNullable(match.getNullable("match")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun sort(): Optional> = Optional.ofNullable(sort.getNullable("sort")) - @JsonProperty("filter") @ExcludeMissing fun _filter() = filter - - @JsonProperty("tag") @ExcludeMissing fun _tag() = tag - - @JsonProperty("match") @ExcludeMissing fun _match() = match + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tag(): Optional> = Optional.ofNullable(tag.getNullable("tag")) - @JsonProperty("sort") @ExcludeMissing fun _sort() = sort + /** + * Returns the raw JSON value of [filter]. + * + * Unlike [filter], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("filter") @ExcludeMissing fun _filter(): JsonField> = filter + + /** + * 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 + + /** + * Returns the raw JSON value of [sort]. + * + * Unlike [sort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sort") @ExcludeMissing fun _sort(): JsonField> = sort + + /** + * Returns the raw JSON value of [tag]. + * + * Unlike [tag], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tag") @ExcludeMissing fun _tag(): JsonField> = tag @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ViewDataSearch = apply { - if (!validated) { - filter() - tag() - match() - sort() - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ViewDataSearch = apply { + if (validated) { + return@apply } - return other is ViewDataSearch && - this.filter == other.filter && - this.tag == other.tag && - this.match == other.match && - this.sort == other.sort && - this.additionalProperties == other.additionalProperties + filter() + match() + sort() + tag() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - filter, - tag, - match, - sort, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ViewDataSearch{filter=$filter, tag=$tag, match=$match, sort=$sort, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ViewDataSearch]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ViewDataSearch]. */ + class Builder internal constructor() { - private var filter: JsonField> = JsonMissing.of() - private var tag: JsonField> = JsonMissing.of() - private var match: JsonField> = JsonMissing.of() - private var sort: JsonField> = JsonMissing.of() + private var filter: JsonField>? = null + private var match: JsonField>? = null + private var sort: JsonField>? = null + private var tag: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(viewDataSearch: ViewDataSearch) = apply { - this.filter = viewDataSearch.filter - this.tag = viewDataSearch.tag - this.match = viewDataSearch.match - this.sort = viewDataSearch.sort - additionalProperties(viewDataSearch.additionalProperties) + filter = viewDataSearch.filter.map { it.toMutableList() } + match = viewDataSearch.match.map { it.toMutableList() } + sort = viewDataSearch.sort.map { it.toMutableList() } + tag = viewDataSearch.tag.map { it.toMutableList() } + additionalProperties = viewDataSearch.additionalProperties.toMutableMap() + } + + fun filter(filter: List?) = filter(JsonField.ofNullable(filter)) + + /** Alias for calling [Builder.filter] with `filter.orElse(null)`. */ + fun filter(filter: Optional>) = filter(filter.getOrNull()) + + /** + * Sets [Builder.filter] to an arbitrary JSON value. + * + * You should usually call [Builder.filter] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun filter(filter: JsonField>) = apply { + this.filter = filter.map { it.toMutableList() } + } + + /** + * Adds a single [JsonValue] to [Builder.filter]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addFilter(filter: JsonValue) = apply { + this.filter = + (this.filter ?: JsonField.of(mutableListOf())).also { + checkKnown("filter", it).add(filter) + } } - fun filter(filter: List) = filter(JsonField.of(filter)) + fun match(match: List?) = match(JsonField.ofNullable(match)) - @JsonProperty("filter") - @ExcludeMissing - fun filter(filter: JsonField>) = apply { this.filter = filter } + /** Alias for calling [Builder.match] with `match.orElse(null)`. */ + fun match(match: Optional>) = match(match.getOrNull()) - fun tag(tag: List) = tag(JsonField.of(tag)) + /** + * 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() } + } - @JsonProperty("tag") - @ExcludeMissing - fun tag(tag: JsonField>) = apply { this.tag = tag } + /** + * Adds a single [JsonValue] to [Builder.match]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addMatch(match: JsonValue) = apply { + this.match = + (this.match ?: JsonField.of(mutableListOf())).also { + checkKnown("match", it).add(match) + } + } - fun match(match: List) = match(JsonField.of(match)) + fun sort(sort: List?) = sort(JsonField.ofNullable(sort)) - @JsonProperty("match") - @ExcludeMissing - fun match(match: JsonField>) = apply { this.match = match } + /** Alias for calling [Builder.sort] with `sort.orElse(null)`. */ + fun sort(sort: Optional>) = sort(sort.getOrNull()) - fun sort(sort: List) = sort(JsonField.of(sort)) + /** + * Sets [Builder.sort] to an arbitrary JSON value. + * + * You should usually call [Builder.sort] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun sort(sort: JsonField>) = apply { + this.sort = sort.map { it.toMutableList() } + } - @JsonProperty("sort") - @ExcludeMissing - fun sort(sort: JsonField>) = apply { this.sort = sort } + /** + * Adds a single [JsonValue] to [Builder.sort]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addSort(sort: JsonValue) = apply { + this.sort = + (this.sort ?: JsonField.of(mutableListOf())).also { + checkKnown("sort", it).add(sort) + } + } + + fun tag(tag: List?) = tag(JsonField.ofNullable(tag)) + + /** Alias for calling [Builder.tag] with `tag.orElse(null)`. */ + fun tag(tag: Optional>) = tag(tag.getOrNull()) + + /** + * Sets [Builder.tag] to an arbitrary JSON value. + * + * You should usually call [Builder.tag] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun tag(tag: JsonField>) = apply { + this.tag = tag.map { it.toMutableList() } + } + + /** + * Adds a single [JsonValue] to [Builder.tag]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTag(tag: JsonValue) = apply { + this.tag = + (this.tag ?: JsonField.of(mutableListOf())).also { checkKnown("tag", it).add(tag) } + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ViewDataSearch]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ViewDataSearch = ViewDataSearch( - filter.map { it.toUnmodifiable() }, - tag.map { it.toUnmodifiable() }, - match.map { it.toUnmodifiable() }, - sort.map { it.toUnmodifiable() }, - additionalProperties.toUnmodifiable(), + (filter ?: JsonMissing.of()).map { it.toImmutable() }, + (match ?: JsonMissing.of()).map { it.toImmutable() }, + (sort ?: JsonMissing.of()).map { it.toImmutable() }, + (tag ?: JsonMissing.of()).map { it.toImmutable() }, + additionalProperties.toImmutable(), ) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewDataSearch && filter == other.filter && match == other.match && sort == other.sort && tag == other.tag && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(filter, match, sort, tag, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ViewDataSearch{filter=$filter, match=$match, sort=$sort, tag=$tag, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDeleteParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDeleteParams.kt index 60e9fa73..75878782 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDeleteParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewDeleteParams.kt @@ -2,49 +2,77 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects +/** Delete a view object by its id */ class ViewDeleteParams -constructor( +private constructor( private val viewId: String, - private val objectId: String, - private val objectType: ObjectType, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** View id */ fun viewId(): String = viewId - fun objectId(): String = objectId + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() - fun objectType(): ObjectType = objectType + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() - @JvmSynthetic - internal fun getBody(): ViewDeleteBody { - return ViewDeleteBody( - objectId, - objectType, - additionalBodyProperties, - ) - } + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -53,347 +81,392 @@ constructor( } } - @JsonDeserialize(builder = ViewDeleteBody.Builder::class) @NoAutoDetect - class ViewDeleteBody - internal constructor( - private val objectId: String?, - private val objectType: ObjectType?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The id of the object the view applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ViewDeleteBody && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.additionalProperties == other.additionalProperties + objectId() + objectType() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectId, - objectType, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ViewDeleteBody{objectId=$objectId, objectType=$objectType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var objectId: String? = null - private var objectType: ObjectType? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(viewDeleteBody: ViewDeleteBody) = apply { - this.objectId = viewDeleteBody.objectId - this.objectType = viewDeleteBody.objectType - additionalProperties(viewDeleteBody.additionalProperties) + internal fun from(body: Body) = apply { + objectId = body.objectId + objectType = body.objectType + additionalProperties = body.additionalProperties.toMutableMap() } /** The id of the object the view applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ViewDeleteBody = - ViewDeleteBody( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - additionalProperties.toUnmodifiable(), - ) - } - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - fun _additionalQueryParams(): Map> = additionalQueryParams + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - fun _additionalHeaders(): Map> = additionalHeaders + /** + * Returns an immutable instance of [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + additionalProperties.toImmutable(), + ) + } - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && objectId == other.objectId && objectType == other.objectType && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ViewDeleteParams && - this.viewId == other.viewId && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - viewId, - objectId, - objectType, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ViewDeleteParams{viewId=$viewId, objectId=$objectId, objectType=$objectType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{objectId=$objectId, objectType=$objectType, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewDeleteParams]. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewDeleteParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var viewId: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(viewDeleteParams: ViewDeleteParams) = apply { - this.viewId = viewDeleteParams.viewId - this.objectId = viewDeleteParams.objectId - this.objectType = viewDeleteParams.objectType - additionalQueryParams(viewDeleteParams.additionalQueryParams) - additionalHeaders(viewDeleteParams.additionalHeaders) - additionalBodyProperties(viewDeleteParams.additionalBodyProperties) + viewId = viewDeleteParams.viewId + body = viewDeleteParams.body.toBuilder() + additionalHeaders = viewDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = viewDeleteParams.additionalQueryParams.toBuilder() } /** View id */ fun viewId(viewId: String) = apply { this.viewId = viewId } /** The id of the object the view applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + 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 removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } fun additionalHeaders(additionalHeaders: Map>) = apply { this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + putAllAdditionalHeaders(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = - apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) - } - - fun build(): ViewDeleteParams = - ViewDeleteParams( - checkNotNull(viewId) { "`viewId` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - return other is ObjectType && this.value == other.value + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - override fun hashCode() = value.hashCode() + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - override fun toString() = value.toString() + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - companion object { + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - } + /** + * Returns an immutable instance of [ViewDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewDeleteParams = + ViewDeleteParams( + checkRequired("viewId", viewId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN - } + return /* spotless:off */ other is ViewDeleteParams && viewId == other.viewId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(viewId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "ViewDeleteParams{viewId=$viewId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPage.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPage.kt index 4fc74c4a..cd5fd5b9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPage.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPage.kt @@ -7,17 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.blocking.ViewService 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.stream.Stream import java.util.stream.StreamSupport +import kotlin.jvm.optionals.getOrNull +/** + * List out all views. The views are sorted by creation date, with the most recently-created views + * coming first + */ class ViewListPage private constructor( private val viewsService: ViewService, @@ -34,19 +40,10 @@ private constructor( return true } - return other is ViewListPage && - this.viewsService == other.viewsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ViewListPage && viewsService == other.viewsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - viewsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(viewsService, params, response) /* spotless:on */ override fun toString() = "ViewListPage{viewsService=$viewsService, params=$params, response=$response}" @@ -81,23 +78,18 @@ private constructor( @JvmStatic fun of(viewsService: ViewService, params: ViewListParams, response: Response) = - ViewListPage( - viewsService, - params, - response, - ) + ViewListPage(viewsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -107,11 +99,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -121,20 +117,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ViewListPage.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ViewListPage]. */ @JvmStatic fun builder() = Builder() } @@ -151,22 +144,22 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ViewListPage, - ) : Iterable { + class AutoPager(private val firstPage: ViewListPage) : Iterable { override fun iterator(): Iterator = iterator { var page = firstPage @@ -175,7 +168,7 @@ private constructor( while (index < page.objects().size) { yield(page.objects()[index++]) } - page = page.getNextPage().orElse(null) ?: break + page = page.getNextPage().getOrNull() ?: break index = 0 } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPageAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPageAsync.kt index f781d4f4..e02a4656 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPageAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListPageAsync.kt @@ -7,18 +7,23 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.services.async.ViewServiceAsync 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional import java.util.concurrent.CompletableFuture import java.util.concurrent.Executor import java.util.function.Predicate +/** + * List out all views. The views are sorted by creation date, with the most recently-created views + * coming first + */ class ViewListPageAsync private constructor( private val viewsService: ViewServiceAsync, @@ -35,19 +40,10 @@ private constructor( return true } - return other is ViewListPageAsync && - this.viewsService == other.viewsService && - this.params == other.params && - this.response == other.response + return /* spotless:off */ other is ViewListPageAsync && viewsService == other.viewsService && params == other.params && response == other.response /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash( - viewsService, - params, - response, - ) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(viewsService, params, response) /* spotless:on */ override fun toString() = "ViewListPageAsync{viewsService=$viewsService, params=$params, response=$response}" @@ -84,23 +80,18 @@ private constructor( @JvmStatic fun of(viewsService: ViewServiceAsync, params: ViewListParams, response: Response) = - ViewListPageAsync( - viewsService, - params, - response, - ) + ViewListPageAsync(viewsService, params, response) } - @JsonDeserialize(builder = Response.Builder::class) @NoAutoDetect class Response + @JsonCreator constructor( - private val objects: JsonField>, - private val additionalProperties: Map, + @JsonProperty("objects") private val objects: JsonField> = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - fun objects(): List = objects.getNullable("objects") ?: listOf() @JsonProperty("objects") @@ -110,11 +101,15 @@ private constructor( @ExcludeMissing fun _additionalProperties(): Map = additionalProperties + private var validated: Boolean = false + fun validate(): Response = apply { - if (!validated) { - objects().map { it.validate() } - validated = true + if (validated) { + return@apply } + + objects().map { it.validate() } + validated = true } fun toBuilder() = Builder().from(this) @@ -124,20 +119,17 @@ private constructor( return true } - return other is Response && - this.objects == other.objects && - this.additionalProperties == other.additionalProperties + return /* spotless:off */ other is Response && objects == other.objects && additionalProperties == other.additionalProperties /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(objects, additionalProperties) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objects, additionalProperties) /* spotless:on */ override fun toString() = - "ViewListPageAsync.Response{objects=$objects, additionalProperties=$additionalProperties}" + "Response{objects=$objects, additionalProperties=$additionalProperties}" companion object { + /** Returns a mutable builder for constructing an instance of [ViewListPageAsync]. */ @JvmStatic fun builder() = Builder() } @@ -154,27 +146,27 @@ private constructor( fun objects(objects: List) = objects(JsonField.of(objects)) - @JsonProperty("objects") fun objects(objects: JsonField>) = apply { this.objects = objects } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { this.additionalProperties.put(key, value) } - fun build() = Response(objects, additionalProperties.toUnmodifiable()) + /** + * Returns an immutable instance of [Response]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Response = Response(objects, additionalProperties.toImmutable()) } } - class AutoPager - constructor( - private val firstPage: ViewListPageAsync, - ) { + class AutoPager(private val firstPage: ViewListPageAsync) { fun forEach(action: Predicate, executor: Executor): CompletableFuture { fun CompletableFuture>.forEach( action: (View) -> Boolean, - executor: Executor + executor: Executor, ): CompletableFuture = thenComposeAsync( { page -> @@ -183,7 +175,7 @@ private constructor( .map { it.getNextPage().forEach(action, executor) } .orElseGet { CompletableFuture.completedFuture(null) } }, - executor + executor, ) return CompletableFuture.completedFuture(Optional.of(firstPage)) .forEach(action::test, executor) diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListParams.kt index 4096d8c8..ef2525d5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewListParams.kt @@ -4,15 +4,14 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.BaseDeserializer import com.braintrustdata.api.core.BaseSerializer -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired import com.braintrustdata.api.core.getOrThrow -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.ObjectCodec import com.fasterxml.jackson.databind.JsonNode @@ -22,134 +21,146 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * List out all views. The views are sorted by creation date, with the most recently-created views + * coming first + */ class ViewListParams -constructor( +private constructor( private val objectId: String, - private val objectType: ObjectType, + private val objectType: AclObjectType, private val endingBefore: String?, private val ids: Ids?, private val limit: Long?, private val startingAfter: String?, private val viewName: String?, private val viewType: ViewType?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** The id of the object the ACL applies to */ fun objectId(): String = objectId - fun objectType(): ObjectType = objectType + /** The object type that the ACL applies to */ + fun objectType(): AclObjectType = objectType + /** + * Pagination cursor id. + * + * For example, if the initial item in the last page you fetched had an id of `foo`, pass + * `ending_before=foo` to fetch the previous page. Note: you may only pass one of + * `starting_after` and `ending_before` + */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ fun ids(): Optional = Optional.ofNullable(ids) + /** Limit the number of objects to return */ fun limit(): Optional = Optional.ofNullable(limit) + /** + * Pagination cursor id. + * + * For example, if the final item in the last page you fetched had an id of `foo`, pass + * `starting_after=foo` to fetch the next page. Note: you may only pass one of `starting_after` + * and `ending_before` + */ fun startingAfter(): Optional = Optional.ofNullable(startingAfter) + /** Name of the view to search for */ fun viewName(): Optional = Optional.ofNullable(viewName) + /** Type of table that the view corresponds to. */ fun viewType(): Optional = Optional.ofNullable(viewType) - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.objectId.let { params.put("object_id", listOf(it.toString())) } - this.objectType.let { params.put("object_type", listOf(it.toString())) } - this.endingBefore?.let { params.put("ending_before", listOf(it.toString())) } - this.ids?.let { params.put("ids", listOf(it.toString())) } - this.limit?.let { params.put("limit", listOf(it.toString())) } - this.startingAfter?.let { params.put("starting_after", listOf(it.toString())) } - this.viewName?.let { params.put("view_name", listOf(it.toString())) } - this.viewType?.let { params.put("view_type", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ViewListParams && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.endingBefore == other.endingBefore && - this.ids == other.ids && - this.limit == other.limit && - this.startingAfter == other.startingAfter && - this.viewName == other.viewName && - this.viewType == other.viewType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - objectId, - objectType, - endingBefore, - ids, - limit, - startingAfter, - viewName, - viewType, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ViewListParams{objectId=$objectId, objectType=$objectType, endingBefore=$endingBefore, ids=$ids, limit=$limit, startingAfter=$startingAfter, viewName=$viewName, viewType=$viewType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + put("object_id", objectId) + put("object_type", objectType.asString()) + endingBefore?.let { put("ending_before", it) } + ids?.accept( + object : Ids.Visitor { + override fun visitString(string: String) { + put("ids", string) + } + + override fun visitStrings(strings: List) { + put("ids", strings.joinToString(",")) + } + } + ) + limit?.let { put("limit", it.toString()) } + startingAfter?.let { put("starting_after", it) } + viewName?.let { put("view_name", it) } + viewType?.let { put("view_type", it.asString()) } + putAll(additionalQueryParams) + } + .build() fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewListParams]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewListParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var objectId: String? = null - private var objectType: ObjectType? = null + private var objectType: AclObjectType? = null private var endingBefore: String? = null private var ids: Ids? = null private var limit: Long? = null private var startingAfter: String? = null private var viewName: String? = null private var viewType: ViewType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(viewListParams: ViewListParams) = apply { - this.objectId = viewListParams.objectId - this.objectType = viewListParams.objectType - this.endingBefore = viewListParams.endingBefore - this.ids = viewListParams.ids - this.limit = viewListParams.limit - this.startingAfter = viewListParams.startingAfter - this.viewName = viewListParams.viewName - this.viewType = viewListParams.viewType - additionalQueryParams(viewListParams.additionalQueryParams) - additionalHeaders(viewListParams.additionalHeaders) + objectId = viewListParams.objectId + objectType = viewListParams.objectType + endingBefore = viewListParams.endingBefore + ids = viewListParams.ids + limit = viewListParams.limit + startingAfter = viewListParams.startingAfter + viewName = viewListParams.viewName + viewType = viewListParams.viewType + additionalHeaders = viewListParams.additionalHeaders.toBuilder() + additionalQueryParams = viewListParams.additionalQueryParams.toBuilder() } /** The id of the object the ACL applies to */ fun objectId(objectId: String) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { this.objectType = objectType } /** * Pagination cursor id. @@ -158,28 +169,38 @@ constructor( * `ending_before=foo` to fetch the previous page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun endingBefore(endingBefore: String) = apply { this.endingBefore = endingBefore } + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } - /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times - */ - fun ids(ids: Ids) = apply { this.ids = ids } + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) /** * Filter search results to a particular set of object IDs. To specify a list of IDs, * include the query param multiple times */ - fun ids(string: String) = apply { this.ids = Ids.ofString(string) } + fun ids(ids: Ids?) = apply { this.ids = ids } + + /** Alias for calling [Builder.ids] with `ids.orElse(null)`. */ + fun ids(ids: Optional) = ids(ids.getOrNull()) + + /** Alias for calling [ids] with `Ids.ofString(string)`. */ + fun ids(string: String) = ids(Ids.ofString(string)) + + /** Alias for calling [ids] with `Ids.ofStrings(strings)`. */ + fun idsOfStrings(strings: List) = ids(Ids.ofStrings(strings)) + + /** Limit the number of objects to return */ + fun limit(limit: Long?) = apply { this.limit = limit } /** - * Filter search results to a particular set of object IDs. To specify a list of IDs, - * include the query param multiple times + * Alias for [Builder.limit]. + * + * This unboxed primitive overload exists for backwards compatibility. */ - fun ids(strings: List) = apply { this.ids = Ids.ofStrings(strings) } + fun limit(limit: Long) = limit(limit as Long?) - /** Limit the number of objects to return */ - fun limit(limit: Long) = apply { this.limit = limit } + /** Alias for calling [Builder.limit] with `limit.orElse(null)`. */ + fun limit(limit: Optional) = limit(limit.getOrNull()) /** * Pagination cursor id. @@ -188,180 +209,154 @@ constructor( * `starting_after=foo` to fetch the next page. Note: you may only pass one of * `starting_after` and `ending_before` */ - fun startingAfter(startingAfter: String) = apply { this.startingAfter = startingAfter } + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } + + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) /** Name of the view to search for */ - fun viewName(viewName: String) = apply { this.viewName = viewName } + fun viewName(viewName: String?) = apply { this.viewName = viewName } + + /** Alias for calling [Builder.viewName] with `viewName.orElse(null)`. */ + fun viewName(viewName: Optional) = viewName(viewName.getOrNull()) /** Type of table that the view corresponds to. */ - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = apply { this.viewType = viewType } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun build(): ViewListParams = - ViewListParams( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - endingBefore, - ids, - limit, - startingAfter, - viewName, - viewType, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - fun asString(): String = _value().asStringOrThrow() + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [ViewListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewListParams = + ViewListParams( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + endingBefore, + ids, + limit, + startingAfter, + viewName, + viewType, + additionalHeaders.build(), + additionalQueryParams.build(), + ) } + /** + * Filter search results to a particular set of object IDs. To specify a list of IDs, include + * the query param multiple times + */ @JsonDeserialize(using = Ids.Deserializer::class) @JsonSerialize(using = Ids.Serializer::class) class Ids @@ -371,8 +366,6 @@ constructor( private val _json: JsonValue? = null, ) { - private var validated: Boolean = false - fun string(): Optional = Optional.ofNullable(string) fun strings(): Optional> = Optional.ofNullable(strings) @@ -395,35 +388,23 @@ constructor( } } - fun validate(): Ids = apply { - if (!validated) { - if (string == null && strings == null) { - throw BraintrustInvalidDataException("Unknown Ids: $_json") - } - validated = true - } - } - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Ids && this.string == other.string && this.strings == other.strings + return /* spotless:off */ other is Ids && string == other.string && strings == other.strings /* spotless:on */ } - override fun hashCode(): Int { - return Objects.hash(string, strings) - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(string, strings) /* spotless:on */ - override fun toString(): String { - return when { + override fun toString(): String = + when { string != null -> "Ids{string=$string}" strings != null -> "Ids{strings=$strings}" _json != null -> "Ids{_unknown=$_json}" else -> throw IllegalStateException("Invalid Ids") } - } companion object { @@ -432,21 +413,32 @@ constructor( @JvmStatic fun ofStrings(strings: List) = Ids(strings = strings) } + /** An interface that defines how to map each variant of [Ids] to a value of type [T]. */ interface Visitor { fun visitString(string: String): T fun visitStrings(strings: List): T + /** + * Maps an unknown variant of [Ids] to a value of type [T]. + * + * An instance of [Ids] can contain an unknown variant if it was deserialized from data + * that doesn't match any known variant. For example, if the SDK is on an older version + * than the API, then the API may respond with new variants that the SDK is unaware of. + * + * @throws BraintrustInvalidDataException in the default implementation. + */ fun unknown(json: JsonValue?): T { throw BraintrustInvalidDataException("Unknown Ids: $json") } } - class Deserializer : BaseDeserializer(Ids::class) { + internal class Deserializer : BaseDeserializer(Ids::class) { override fun ObjectCodec.deserialize(node: JsonNode): Ids { val json = JsonValue.fromJsonNode(node) + tryDeserialize(node, jacksonTypeRef())?.let { return Ids(string = it, _json = json) } @@ -458,12 +450,12 @@ constructor( } } - class Serializer : BaseSerializer(Ids::class) { + internal class Serializer : BaseSerializer(Ids::class) { override fun serialize( value: Ids, generator: JsonGenerator, - provider: SerializerProvider + provider: SerializerProvider, ) { when { value.string != null -> generator.writeObject(value.string) @@ -475,96 +467,16 @@ constructor( } } - class ViewType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ViewType && this.value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val PROJECTS = ViewType(JsonField.of("projects")) - - @JvmField val LOGS = ViewType(JsonField.of("logs")) - - @JvmField val EXPERIMENTS = ViewType(JsonField.of("experiments")) - - @JvmField val DATASETS = ViewType(JsonField.of("datasets")) - - @JvmField val PROMPTS = ViewType(JsonField.of("prompts")) - - @JvmField val PLAYGROUNDS = ViewType(JsonField.of("playgrounds")) - - @JvmField val EXPERIMENT = ViewType(JsonField.of("experiment")) - - @JvmField val DATASET = ViewType(JsonField.of("dataset")) - - @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) - } - - enum class Known { - PROJECTS, - LOGS, - EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, - EXPERIMENT, - DATASET, - } - - enum class Value { - PROJECTS, - LOGS, - EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, - EXPERIMENT, - DATASET, - _UNKNOWN, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - fun value(): Value = - when (this) { - PROJECTS -> Value.PROJECTS - LOGS -> Value.LOGS - EXPERIMENTS -> Value.EXPERIMENTS - DATASETS -> Value.DATASETS - PROMPTS -> Value.PROMPTS - PLAYGROUNDS -> Value.PLAYGROUNDS - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - else -> Value._UNKNOWN - } + return /* spotless:off */ other is ViewListParams && objectId == other.objectId && objectType == other.objectType && endingBefore == other.endingBefore && ids == other.ids && limit == other.limit && startingAfter == other.startingAfter && viewName == other.viewName && viewType == other.viewType && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } - fun known(): Known = - when (this) { - PROJECTS -> Known.PROJECTS - LOGS -> Known.LOGS - EXPERIMENTS -> Known.EXPERIMENTS - DATASETS -> Known.DATASETS - PROMPTS -> Known.PROMPTS - PLAYGROUNDS -> Known.PLAYGROUNDS - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") - } + override fun hashCode(): Int = /* spotless:off */ Objects.hash(objectId, objectType, endingBefore, ids, limit, startingAfter, viewName, viewType, additionalHeaders, additionalQueryParams) /* spotless:on */ - fun asString(): String = _value().asStringOrThrow() - } + override fun toString() = + "ViewListParams{objectId=$objectId, objectType=$objectType, endingBefore=$endingBefore, ids=$ids, limit=$limit, startingAfter=$startingAfter, viewName=$viewName, viewType=$viewType, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewOptions.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewOptions.kt index f47bc870..bf4af30f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewOptions.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewOptions.kt @@ -7,297 +7,504 @@ import com.braintrustdata.api.core.JsonField import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.checkKnown +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable +import com.braintrustdata.api.errors.BraintrustInvalidDataException 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** Options for the view in the app */ -@JsonDeserialize(builder = ViewOptions.Builder::class) @NoAutoDetect class ViewOptions +@JsonCreator private constructor( - private val columnVisibility: JsonField, - private val columnOrder: JsonField>, - private val columnSizing: JsonField, - private val additionalProperties: Map, + @JsonProperty("columnOrder") + @ExcludeMissing + private val columnOrder: JsonField> = JsonMissing.of(), + @JsonProperty("columnSizing") + @ExcludeMissing + private val columnSizing: JsonField = JsonMissing.of(), + @JsonProperty("columnVisibility") + @ExcludeMissing + private val columnVisibility: JsonField = JsonMissing.of(), + @JsonProperty("grouping") + @ExcludeMissing + private val grouping: JsonField = JsonMissing.of(), + @JsonProperty("layout") + @ExcludeMissing + private val layout: JsonField = JsonMissing.of(), + @JsonProperty("rowHeight") + @ExcludeMissing + private val rowHeight: JsonField = JsonMissing.of(), + @JsonAnySetter private val additionalProperties: Map = immutableEmptyMap(), ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - - fun columnVisibility(): Optional = - Optional.ofNullable(columnVisibility.getNullable("columnVisibility")) - + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun columnOrder(): Optional> = Optional.ofNullable(columnOrder.getNullable("columnOrder")) + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ fun columnSizing(): Optional = Optional.ofNullable(columnSizing.getNullable("columnSizing")) - @JsonProperty("columnVisibility") @ExcludeMissing fun _columnVisibility() = columnVisibility - - @JsonProperty("columnOrder") @ExcludeMissing fun _columnOrder() = columnOrder + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun columnVisibility(): Optional = + Optional.ofNullable(columnVisibility.getNullable("columnVisibility")) - @JsonProperty("columnSizing") @ExcludeMissing fun _columnSizing() = columnSizing + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun grouping(): Optional = Optional.ofNullable(grouping.getNullable("grouping")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun layout(): Optional = Optional.ofNullable(layout.getNullable("layout")) + + /** + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rowHeight(): Optional = Optional.ofNullable(rowHeight.getNullable("rowHeight")) + + /** + * Returns the raw JSON value of [columnOrder]. + * + * Unlike [columnOrder], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("columnOrder") + @ExcludeMissing + fun _columnOrder(): JsonField> = columnOrder + + /** + * Returns the raw JSON value of [columnSizing]. + * + * Unlike [columnSizing], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("columnSizing") + @ExcludeMissing + fun _columnSizing(): JsonField = columnSizing + + /** + * Returns the raw JSON value of [columnVisibility]. + * + * Unlike [columnVisibility], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("columnVisibility") + @ExcludeMissing + fun _columnVisibility(): JsonField = columnVisibility + + /** + * Returns the raw JSON value of [grouping]. + * + * Unlike [grouping], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("grouping") @ExcludeMissing fun _grouping(): JsonField = grouping + + /** + * Returns the raw JSON value of [layout]. + * + * Unlike [layout], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("layout") @ExcludeMissing fun _layout(): JsonField = layout + + /** + * Returns the raw JSON value of [rowHeight]. + * + * Unlike [rowHeight], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rowHeight") @ExcludeMissing fun _rowHeight(): JsonField = rowHeight @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ViewOptions = apply { - if (!validated) { - columnVisibility().map { it.validate() } - columnOrder() - columnSizing().map { it.validate() } - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ViewOptions = apply { + if (validated) { + return@apply } - return other is ViewOptions && - this.columnVisibility == other.columnVisibility && - this.columnOrder == other.columnOrder && - this.columnSizing == other.columnSizing && - this.additionalProperties == other.additionalProperties + columnOrder() + columnSizing().ifPresent { it.validate() } + columnVisibility().ifPresent { it.validate() } + grouping() + layout() + rowHeight() + validated = true } - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - columnVisibility, - columnOrder, - columnSizing, - additionalProperties, - ) - } - return hashCode - } - - override fun toString() = - "ViewOptions{columnVisibility=$columnVisibility, columnOrder=$columnOrder, columnSizing=$columnSizing, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ViewOptions]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ViewOptions]. */ + class Builder internal constructor() { - private var columnVisibility: JsonField = JsonMissing.of() - private var columnOrder: JsonField> = JsonMissing.of() + private var columnOrder: JsonField>? = null private var columnSizing: JsonField = JsonMissing.of() + private var columnVisibility: JsonField = JsonMissing.of() + private var grouping: JsonField = JsonMissing.of() + private var layout: JsonField = JsonMissing.of() + private var rowHeight: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(viewOptions: ViewOptions) = apply { - this.columnVisibility = viewOptions.columnVisibility - this.columnOrder = viewOptions.columnOrder - this.columnSizing = viewOptions.columnSizing - additionalProperties(viewOptions.additionalProperties) + columnOrder = viewOptions.columnOrder.map { it.toMutableList() } + columnSizing = viewOptions.columnSizing + columnVisibility = viewOptions.columnVisibility + grouping = viewOptions.grouping + layout = viewOptions.layout + rowHeight = viewOptions.rowHeight + additionalProperties = viewOptions.additionalProperties.toMutableMap() } - fun columnVisibility(columnVisibility: ColumnVisibility) = - columnVisibility(JsonField.of(columnVisibility)) + fun columnOrder(columnOrder: List?) = columnOrder(JsonField.ofNullable(columnOrder)) - @JsonProperty("columnVisibility") - @ExcludeMissing - fun columnVisibility(columnVisibility: JsonField) = apply { - this.columnVisibility = columnVisibility - } - - fun columnOrder(columnOrder: List) = columnOrder(JsonField.of(columnOrder)) + /** Alias for calling [Builder.columnOrder] with `columnOrder.orElse(null)`. */ + fun columnOrder(columnOrder: Optional>) = columnOrder(columnOrder.getOrNull()) - @JsonProperty("columnOrder") - @ExcludeMissing + /** + * Sets [Builder.columnOrder] to an arbitrary JSON value. + * + * You should usually call [Builder.columnOrder] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun columnOrder(columnOrder: JsonField>) = apply { - this.columnOrder = columnOrder + this.columnOrder = columnOrder.map { it.toMutableList() } + } + + /** + * Adds a single [String] to [Builder.columnOrder]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addColumnOrder(columnOrder: String) = apply { + this.columnOrder = + (this.columnOrder ?: JsonField.of(mutableListOf())).also { + checkKnown("columnOrder", it).add(columnOrder) + } } - fun columnSizing(columnSizing: ColumnSizing) = columnSizing(JsonField.of(columnSizing)) + fun columnSizing(columnSizing: ColumnSizing?) = + columnSizing(JsonField.ofNullable(columnSizing)) - @JsonProperty("columnSizing") - @ExcludeMissing + /** Alias for calling [Builder.columnSizing] with `columnSizing.orElse(null)`. */ + fun columnSizing(columnSizing: Optional) = + columnSizing(columnSizing.getOrNull()) + + /** + * Sets [Builder.columnSizing] to an arbitrary JSON value. + * + * You should usually call [Builder.columnSizing] with a well-typed [ColumnSizing] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ fun columnSizing(columnSizing: JsonField) = apply { this.columnSizing = columnSizing } + fun columnVisibility(columnVisibility: ColumnVisibility?) = + columnVisibility(JsonField.ofNullable(columnVisibility)) + + /** Alias for calling [Builder.columnVisibility] with `columnVisibility.orElse(null)`. */ + fun columnVisibility(columnVisibility: Optional) = + columnVisibility(columnVisibility.getOrNull()) + + /** + * Sets [Builder.columnVisibility] to an arbitrary JSON value. + * + * You should usually call [Builder.columnVisibility] with a well-typed [ColumnVisibility] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun columnVisibility(columnVisibility: JsonField) = apply { + this.columnVisibility = columnVisibility + } + + fun grouping(grouping: String?) = grouping(JsonField.ofNullable(grouping)) + + /** Alias for calling [Builder.grouping] with `grouping.orElse(null)`. */ + fun grouping(grouping: Optional) = grouping(grouping.getOrNull()) + + /** + * Sets [Builder.grouping] to an arbitrary JSON value. + * + * You should usually call [Builder.grouping] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun grouping(grouping: JsonField) = apply { this.grouping = grouping } + + fun layout(layout: String?) = layout(JsonField.ofNullable(layout)) + + /** Alias for calling [Builder.layout] with `layout.orElse(null)`. */ + fun layout(layout: Optional) = layout(layout.getOrNull()) + + /** + * Sets [Builder.layout] to an arbitrary JSON value. + * + * You should usually call [Builder.layout] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun layout(layout: JsonField) = apply { this.layout = layout } + + fun rowHeight(rowHeight: String?) = rowHeight(JsonField.ofNullable(rowHeight)) + + /** Alias for calling [Builder.rowHeight] with `rowHeight.orElse(null)`. */ + fun rowHeight(rowHeight: Optional) = rowHeight(rowHeight.getOrNull()) + + /** + * Sets [Builder.rowHeight] to an arbitrary JSON value. + * + * You should usually call [Builder.rowHeight] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun rowHeight(rowHeight: JsonField) = apply { this.rowHeight = rowHeight } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + 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 [ViewOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ fun build(): ViewOptions = ViewOptions( - columnVisibility, - columnOrder.map { it.toUnmodifiable() }, + (columnOrder ?: JsonMissing.of()).map { it.toImmutable() }, columnSizing, - additionalProperties.toUnmodifiable(), + columnVisibility, + grouping, + layout, + rowHeight, + additionalProperties.toImmutable(), ) } - @JsonDeserialize(builder = ColumnSizing.Builder::class) @NoAutoDetect class ColumnSizing + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ColumnSizing = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ColumnSizing = apply { + if (validated) { + return@apply } - return other is ColumnSizing && this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "ColumnSizing{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ColumnSizing]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ColumnSizing]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(columnSizing: ColumnSizing) = apply { - additionalProperties(columnSizing.additionalProperties) + additionalProperties = columnSizing.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ColumnSizing = ColumnSizing(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ColumnSizing]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ColumnSizing = ColumnSizing(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ColumnSizing && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "ColumnSizing{additionalProperties=$additionalProperties}" } - @JsonDeserialize(builder = ColumnVisibility.Builder::class) @NoAutoDetect class ColumnVisibility + @JsonCreator private constructor( - private val additionalProperties: Map, + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap() ) { - private var validated: Boolean = false - - private var hashCode: Int = 0 - @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun validate(): ColumnVisibility = apply { - if (!validated) { - validated = true - } - } - - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): ColumnVisibility = apply { + if (validated) { + return@apply } - return other is ColumnVisibility && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = Objects.hash(additionalProperties) - } - return hashCode + validated = true } - override fun toString() = "ColumnVisibility{additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** Returns a mutable builder for constructing an instance of [ColumnVisibility]. */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [ColumnVisibility]. */ + class Builder internal constructor() { private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(columnVisibility: ColumnVisibility) = apply { - additionalProperties(columnVisibility.additionalProperties) + additionalProperties = columnVisibility.additionalProperties.toMutableMap() } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ColumnVisibility = ColumnVisibility(additionalProperties.toUnmodifiable()) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ColumnVisibility]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ColumnVisibility = ColumnVisibility(additionalProperties.toImmutable()) } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ColumnVisibility && additionalProperties == other.additionalProperties /* spotless:on */ + } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = "ColumnVisibility{additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewOptions && columnOrder == other.columnOrder && columnSizing == other.columnSizing && columnVisibility == other.columnVisibility && grouping == other.grouping && layout == other.layout && rowHeight == other.rowHeight && additionalProperties == other.additionalProperties /* spotless:on */ } + + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(columnOrder, columnSizing, columnVisibility, grouping, layout, rowHeight, additionalProperties) } + /* spotless:on */ + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ViewOptions{columnOrder=$columnOrder, columnSizing=$columnSizing, columnVisibility=$columnVisibility, grouping=$grouping, layout=$layout, rowHeight=$rowHeight, additionalProperties=$additionalProperties}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewReplaceParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewReplaceParams.kt index e49681ca..8f84c8c9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewReplaceParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewReplaceParams.kt @@ -5,620 +5,1018 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.time.OffsetDateTime import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Create or replace view. If there is an existing view with the same name as the one specified in + * the request, will replace the existing view with the provided fields + */ class ViewReplaceParams -constructor( - private val name: String, - private val objectId: String, - private val objectType: ObjectType, - private val viewType: ViewType?, - private val deletedAt: OffsetDateTime?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { - - fun name(): String = name - - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun viewType(): Optional = Optional.ofNullable(viewType) - - fun deletedAt(): Optional = Optional.ofNullable(deletedAt) - - fun options(): Optional = Optional.ofNullable(options) - - fun userId(): Optional = Optional.ofNullable(userId) - - fun viewData(): Optional = Optional.ofNullable(viewData) - - @JvmSynthetic - internal fun getBody(): ViewReplaceBody { - return ViewReplaceBody( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams +private constructor( + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** + * Name of the view + * + * @throws BraintrustInvalidDataException 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() + + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewType(): Optional = body.viewType() + + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun deletedAt(): Optional = body.deletedAt() + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewData(): Optional = body.viewData() + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewType(): JsonField = body._viewType() + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _deletedAt(): JsonField = body._deletedAt() + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewData(): JsonField = body._viewData() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders - - @JsonDeserialize(builder = ViewReplaceBody.Builder::class) @NoAutoDetect - class ViewReplaceBody - internal constructor( - private val name: String?, - private val objectId: String?, - private val objectType: ObjectType?, - private val viewType: ViewType?, - private val deletedAt: OffsetDateTime?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("view_type") + @ExcludeMissing + private val viewType: JsonField = JsonMissing.of(), + @JsonProperty("deleted_at") + @ExcludeMissing + private val deletedAt: JsonField = JsonMissing.of(), + @JsonProperty("options") + @ExcludeMissing + private val options: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("view_data") + @ExcludeMissing + private val viewData: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** Name of the view */ - @JsonProperty("name") fun name(): String? = name - - /** The id of the object the view applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType - - /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") fun viewType(): ViewType? = viewType - - /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") fun deletedAt(): OffsetDateTime? = deletedAt - - /** Options for the view in the app */ - @JsonProperty("options") fun options(): ViewOptions? = options - - /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(): String? = userId - - /** The view definition */ - @JsonProperty("view_data") fun viewData(): ViewData? = viewData + /** + * Name of the view + * + * @throws BraintrustInvalidDataException 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") + + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewType(): Optional = Optional.ofNullable(viewType.getNullable("view_type")) + + /** + * Date of role deletion, or null if the role is still active + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun deletedAt(): Optional = + Optional.ofNullable(deletedAt.getNullable("deleted_at")) + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = Optional.ofNullable(options.getNullable("options")) + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewData(): Optional = Optional.ofNullable(viewData.getNullable("view_data")) + + /** + * 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 [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_type") @ExcludeMissing fun _viewType(): JsonField = viewType + + /** + * Returns the raw JSON value of [deletedAt]. + * + * Unlike [deletedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("deleted_at") + @ExcludeMissing + fun _deletedAt(): JsonField = deletedAt + + /** + * Returns the raw JSON value of [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_data") @ExcludeMissing fun _viewData(): JsonField = viewData @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ViewReplaceBody && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.viewType == other.viewType && - this.deletedAt == other.deletedAt && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalProperties, - ) - } - return hashCode + name() + objectId() + objectType() + viewType() + deletedAt() + options().ifPresent { it.validate() } + userId() + viewData().ifPresent { it.validate() } + validated = true } - override fun toString() = - "ViewReplaceBody{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalProperties=$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() + * .objectId() + * .objectType() + * .viewType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { - - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var viewType: ViewType? = null - private var deletedAt: OffsetDateTime? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var name: JsonField? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var viewType: JsonField? = null + private var deletedAt: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() + private var viewData: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(viewReplaceBody: ViewReplaceBody) = apply { - this.name = viewReplaceBody.name - this.objectId = viewReplaceBody.objectId - this.objectType = viewReplaceBody.objectType - this.viewType = viewReplaceBody.viewType - this.deletedAt = viewReplaceBody.deletedAt - this.options = viewReplaceBody.options - this.userId = viewReplaceBody.userId - this.viewData = viewReplaceBody.viewData - additionalProperties(viewReplaceBody.additionalProperties) + internal fun from(body: Body) = apply { + name = body.name + objectId = body.objectId + objectType = body.objectType + viewType = body.viewType + deletedAt = body.deletedAt + options = body.options + userId = body.userId + viewData = body.viewData + additionalProperties = body.additionalProperties.toMutableMap() } /** Name of the view */ - @JsonProperty("name") fun name(name: String) = apply { this.name = 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 } /** The id of the object the view applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = viewType(JsonField.ofNullable(viewType)) + + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) + + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewType(viewType: JsonField) = apply { this.viewType = viewType } /** Date of role deletion, or null if the role is still active */ - @JsonProperty("deleted_at") - fun deletedAt(deletedAt: OffsetDateTime) = apply { this.deletedAt = deletedAt } + fun deletedAt(deletedAt: OffsetDateTime?) = deletedAt(JsonField.ofNullable(deletedAt)) + + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) + + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { + this.deletedAt = deletedAt + } /** Options for the view in the app */ - @JsonProperty("options") - fun options(options: ViewOptions) = apply { this.options = options } + fun options(options: ViewOptions?) = options(JsonField.ofNullable(options)) + + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } /** The view definition */ - @JsonProperty("view_data") - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + fun viewData(viewData: ViewData?) = viewData(JsonField.ofNullable(viewData)) + + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) + + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewData(viewData: JsonField) = apply { this.viewData = viewData } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ViewReplaceBody = - ViewReplaceBody( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - viewType, + 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() + * .objectId() + * .objectType() + * .viewType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("name", name), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + checkRequired("viewType", viewType), deletedAt, options, userId, viewData, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && name == other.name && objectId == other.objectId && objectType == other.objectType && viewType == other.viewType && deletedAt == other.deletedAt && options == other.options && userId == other.userId && viewData == other.viewData && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ViewReplaceParams && - this.name == other.name && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.viewType == other.viewType && - this.deletedAt == other.deletedAt && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(name, objectId, objectType, viewType, deletedAt, options, userId, viewData, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - name, - objectId, - objectType, - viewType, - deletedAt, - options, - userId, - viewData, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ViewReplaceParams{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{name=$name, objectId=$objectId, objectType=$objectType, viewType=$viewType, deletedAt=$deletedAt, options=$options, userId=$userId, viewData=$viewData, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewReplaceParams]. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewReplaceParams]. */ @NoAutoDetect - class Builder { - - private var name: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var viewType: ViewType? = null - private var deletedAt: OffsetDateTime? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + class Builder internal constructor() { + + 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(viewReplaceParams: ViewReplaceParams) = apply { - this.name = viewReplaceParams.name - this.objectId = viewReplaceParams.objectId - this.objectType = viewReplaceParams.objectType - this.viewType = viewReplaceParams.viewType - this.deletedAt = viewReplaceParams.deletedAt - this.options = viewReplaceParams.options - this.userId = viewReplaceParams.userId - this.viewData = viewReplaceParams.viewData - additionalQueryParams(viewReplaceParams.additionalQueryParams) - additionalHeaders(viewReplaceParams.additionalHeaders) - additionalBodyProperties(viewReplaceParams.additionalBodyProperties) + body = viewReplaceParams.body.toBuilder() + additionalHeaders = viewReplaceParams.additionalHeaders.toBuilder() + additionalQueryParams = viewReplaceParams.additionalQueryParams.toBuilder() } /** Name of the view */ - fun name(name: String) = apply { this.name = 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) } /** The id of the object the view applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** Type of table that the view corresponds to. */ - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = apply { body.viewType(viewType) } - /** Date of role deletion, or null if the role is still active */ - fun deletedAt(deletedAt: OffsetDateTime) = apply { this.deletedAt = deletedAt } + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) - /** Options for the view in the app */ - fun options(options: ViewOptions) = apply { this.options = options } + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewType(viewType: JsonField) = apply { body.viewType(viewType) } - /** Identifies the user who created the view */ - fun userId(userId: String) = apply { this.userId = userId } + /** Date of role deletion, or null if the role is still active */ + fun deletedAt(deletedAt: OffsetDateTime?) = apply { body.deletedAt(deletedAt) } - /** The view definition */ - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + /** Alias for calling [Builder.deletedAt] with `deletedAt.orElse(null)`. */ + fun deletedAt(deletedAt: Optional) = deletedAt(deletedAt.getOrNull()) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.deletedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.deletedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun deletedAt(deletedAt: JsonField) = apply { body.deletedAt(deletedAt) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } + /** Options for the view in the app */ + fun options(options: ViewOptions?) = apply { body.options(options) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun options(options: JsonField) = apply { body.options(options) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** Identifies the user who created the view */ + fun userId(userId: String?) = apply { body.userId(userId) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** The view definition */ + fun viewData(viewData: ViewData?) = apply { body.viewData(viewData) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewData(viewData: JsonField) = apply { body.viewData(viewData) } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.additionalProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + body.putAdditionalProperty(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.putAllAdditionalProperties(additionalBodyProperties) } - fun build(): ViewReplaceParams = - ViewReplaceParams( - checkNotNull(name) { "`name` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - viewType, - deletedAt, - options, - userId, - viewData, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - return other is ObjectType && this.value == other.value + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - override fun hashCode() = value.hashCode() + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } - override fun toString() = value.toString() + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - companion object { + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - fun asString(): String = _value().asStringOrThrow() - } + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } - class ViewType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** + * Returns an immutable instance of [ViewReplaceParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .name() + * .objectId() + * .objectType() + * .viewType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewReplaceParams = + ViewReplaceParams( + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + /** Type of table that the view corresponds to. */ + class ViewType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + companion object { - return other is ViewType && this.value == other.value - } + @JvmField val PROJECTS = of("projects") - override fun hashCode() = value.hashCode() + @JvmField val EXPERIMENTS = of("experiments") - override fun toString() = value.toString() + @JvmField val EXPERIMENT = of("experiment") - companion object { + @JvmField val PLAYGROUNDS = of("playgrounds") - @JvmField val PROJECTS = ViewType(JsonField.of("projects")) + @JvmField val PLAYGROUND = of("playground") - @JvmField val LOGS = ViewType(JsonField.of("logs")) + @JvmField val DATASETS = of("datasets") - @JvmField val EXPERIMENTS = ViewType(JsonField.of("experiments")) + @JvmField val DATASET = of("dataset") - @JvmField val DATASETS = ViewType(JsonField.of("datasets")) + @JvmField val PROMPTS = of("prompts") - @JvmField val PROMPTS = ViewType(JsonField.of("prompts")) + @JvmField val TOOLS = of("tools") - @JvmField val PLAYGROUNDS = ViewType(JsonField.of("playgrounds")) + @JvmField val SCORERS = of("scorers") - @JvmField val EXPERIMENT = ViewType(JsonField.of("experiment")) - - @JvmField val DATASET = ViewType(JsonField.of("dataset")) + @JvmField val LOGS = of("logs") @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) } + /** An enum containing [ViewType]'s known values. */ enum class Known { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, } + /** + * An enum containing [ViewType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ViewType] 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 { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + /** An enum member indicating that [ViewType] 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) { PROJECTS -> Value.PROJECTS - LOGS -> Value.LOGS EXPERIMENTS -> Value.EXPERIMENTS - DATASETS -> Value.DATASETS - PROMPTS -> Value.PROMPTS - PLAYGROUNDS -> Value.PLAYGROUNDS EXPERIMENT -> Value.EXPERIMENT + PLAYGROUNDS -> Value.PLAYGROUNDS + PLAYGROUND -> Value.PLAYGROUND + DATASETS -> Value.DATASETS DATASET -> Value.DATASET + PROMPTS -> Value.PROMPTS + TOOLS -> Value.TOOLS + SCORERS -> Value.SCORERS + LOGS -> Value.LOGS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { PROJECTS -> Known.PROJECTS - LOGS -> Known.LOGS EXPERIMENTS -> Known.EXPERIMENTS - DATASETS -> Known.DATASETS - PROMPTS -> Known.PROMPTS - PLAYGROUNDS -> Known.PLAYGROUNDS EXPERIMENT -> Known.EXPERIMENT + PLAYGROUNDS -> Known.PLAYGROUNDS + PLAYGROUND -> Known.PLAYGROUND + DATASETS -> Known.DATASETS DATASET -> Known.DATASET + PROMPTS -> Known.PROMPTS + TOOLS -> Known.TOOLS + SCORERS -> Known.SCORERS + LOGS -> Known.LOGS else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewReplaceParams && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ViewReplaceParams{body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewRetrieveParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewRetrieveParams.kt index b56ed968..0e6067a2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewRetrieveParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewRetrieveParams.kt @@ -2,41 +2,46 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.JsonField -import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable -import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.annotation.JsonCreator +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams import java.util.Objects +/** Get a view object by its id */ class ViewRetrieveParams -constructor( +private constructor( private val viewId: String, private val objectId: String, - private val objectType: ObjectType, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, -) { + private val objectType: AclObjectType, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** View id */ fun viewId(): String = viewId + /** The id of the object the ACL applies to */ fun objectId(): String = objectId - fun objectType(): ObjectType = objectType + /** The object type that the ACL applies to */ + fun objectType(): AclObjectType = objectType - @JvmSynthetic - internal fun getQueryParams(): Map> { - val params = mutableMapOf>() - this.objectId.let { params.put("object_id", listOf(it.toString())) } - this.objectType.let { params.put("object_type", listOf(it.toString())) } - params.putAll(additionalQueryParams) - return params.toUnmodifiable() - } + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + put("object_id", objectId) + put("object_type", objectType.asString()) + putAll(additionalQueryParams) + } + .build() fun getPathParam(index: Int): String { return when (index) { @@ -45,59 +50,40 @@ constructor( } } - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ViewRetrieveParams && - this.viewId == other.viewId && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders - } - - override fun hashCode(): Int { - return Objects.hash( - viewId, - objectId, - objectType, - additionalQueryParams, - additionalHeaders, - ) - } - - override fun toString() = - "ViewRetrieveParams{viewId=$viewId, objectId=$objectId, objectType=$objectType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders}" - fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewRetrieveParams]. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewRetrieveParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var viewId: String? = null private var objectId: String? = null - private var objectType: ObjectType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() + private var objectType: AclObjectType? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() @JvmSynthetic internal fun from(viewRetrieveParams: ViewRetrieveParams) = apply { - this.viewId = viewRetrieveParams.viewId - this.objectId = viewRetrieveParams.objectId - this.objectType = viewRetrieveParams.objectType - additionalQueryParams(viewRetrieveParams.additionalQueryParams) - additionalHeaders(viewRetrieveParams.additionalHeaders) + viewId = viewRetrieveParams.viewId + objectId = viewRetrieveParams.objectId + objectType = viewRetrieveParams.objectType + additionalHeaders = viewRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = viewRetrieveParams.additionalQueryParams.toBuilder() } /** View id */ @@ -107,166 +93,140 @@ constructor( fun objectId(objectId: String) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { this.objectType = objectType } - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) } - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } - - fun build(): ViewRetrieveParams = - ViewRetrieveParams( - checkNotNull(viewId) { "`viewId` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - ) - } - - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { - - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is ObjectType && this.value == other.value + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - - companion object { - - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) - - @JvmField val PROJECT = ObjectType(JsonField.of("project")) - - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) - - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [ViewRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewRetrieveParams = + ViewRetrieveParams( + checkRequired("viewId", viewId), + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } - fun asString(): String = _value().asStringOrThrow() + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewRetrieveParams && viewId == other.viewId && objectId == other.objectId && objectType == other.objectType && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(viewId, objectId, objectType, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ViewRetrieveParams{viewId=$viewId, objectId=$objectId, objectType=$objectType, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewType.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewType.kt new file mode 100644 index 00000000..f09a7f19 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewType.kt @@ -0,0 +1,160 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.Enum +import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.errors.BraintrustInvalidDataException +import com.fasterxml.jackson.annotation.JsonCreator + +/** Type of table that the view corresponds to. */ +class ViewType @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 PROJECTS = of("projects") + + @JvmField val EXPERIMENTS = of("experiments") + + @JvmField val EXPERIMENT = of("experiment") + + @JvmField val PLAYGROUNDS = of("playgrounds") + + @JvmField val PLAYGROUND = of("playground") + + @JvmField val DATASETS = of("datasets") + + @JvmField val DATASET = of("dataset") + + @JvmField val PROMPTS = of("prompts") + + @JvmField val TOOLS = of("tools") + + @JvmField val SCORERS = of("scorers") + + @JvmField val LOGS = of("logs") + + @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) + } + + /** An enum containing [ViewType]'s known values. */ + enum class Known { + PROJECTS, + EXPERIMENTS, + EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, + DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + } + + /** + * An enum containing [ViewType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ViewType] 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 { + PROJECTS, + EXPERIMENTS, + EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, + DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + /** An enum member indicating that [ViewType] 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) { + PROJECTS -> Value.PROJECTS + EXPERIMENTS -> Value.EXPERIMENTS + EXPERIMENT -> Value.EXPERIMENT + PLAYGROUNDS -> Value.PLAYGROUNDS + PLAYGROUND -> Value.PLAYGROUND + DATASETS -> Value.DATASETS + DATASET -> Value.DATASET + PROMPTS -> Value.PROMPTS + TOOLS -> Value.TOOLS + SCORERS -> Value.SCORERS + LOGS -> Value.LOGS + 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + PROJECTS -> Known.PROJECTS + EXPERIMENTS -> Known.EXPERIMENTS + EXPERIMENT -> Known.EXPERIMENT + PLAYGROUNDS -> Known.PLAYGROUNDS + PLAYGROUND -> Known.PLAYGROUND + DATASETS -> Known.DATASETS + DATASET -> Known.DATASET + PROMPTS -> Known.PROMPTS + TOOLS -> Known.TOOLS + SCORERS -> Known.SCORERS + LOGS -> Known.LOGS + else -> throw BraintrustInvalidDataException("Unknown ViewType: $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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { BraintrustInvalidDataException("Value is not a String") } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewUpdateParams.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewUpdateParams.kt index 3bb1d99d..1d810b26 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewUpdateParams.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/models/ViewUpdateParams.kt @@ -5,67 +5,156 @@ package com.braintrustdata.api.models import com.braintrustdata.api.core.Enum import com.braintrustdata.api.core.ExcludeMissing import com.braintrustdata.api.core.JsonField +import com.braintrustdata.api.core.JsonMissing import com.braintrustdata.api.core.JsonValue import com.braintrustdata.api.core.NoAutoDetect -import com.braintrustdata.api.core.toUnmodifiable +import com.braintrustdata.api.core.Params +import com.braintrustdata.api.core.checkRequired +import com.braintrustdata.api.core.http.Headers +import com.braintrustdata.api.core.http.QueryParams +import com.braintrustdata.api.core.immutableEmptyMap +import com.braintrustdata.api.core.toImmutable import com.braintrustdata.api.errors.BraintrustInvalidDataException -import com.braintrustdata.api.models.* 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.fasterxml.jackson.databind.annotation.JsonDeserialize import java.util.Objects import java.util.Optional +import kotlin.jvm.optionals.getOrNull +/** + * Partially update a view object. Specify the fields to update in the payload. Any object-type + * fields will be deep-merged with existing content. Currently we do not support removing fields or + * setting them to null. + */ class ViewUpdateParams -constructor( +private constructor( private val viewId: String, - private val objectId: String, - private val objectType: ObjectType, - private val name: String?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val viewType: ViewType?, - private val additionalQueryParams: Map>, - private val additionalHeaders: Map>, - private val additionalBodyProperties: Map, -) { + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + /** View id */ fun viewId(): String = viewId - fun objectId(): String = objectId - - fun objectType(): ObjectType = objectType - - fun name(): Optional = Optional.ofNullable(name) - - fun options(): Optional = Optional.ofNullable(options) - - fun userId(): Optional = Optional.ofNullable(userId) - - fun viewData(): Optional = Optional.ofNullable(viewData) - - fun viewType(): Optional = Optional.ofNullable(viewType) - - @JvmSynthetic - internal fun getBody(): ViewUpdateBody { - return ViewUpdateBody( - objectId, - objectType, - name, - options, - userId, - viewData, - viewType, - additionalBodyProperties, - ) - } - - @JvmSynthetic internal fun getQueryParams(): Map> = additionalQueryParams - - @JvmSynthetic internal fun getHeaders(): Map> = additionalHeaders + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = body.objectId() + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = body.objectType() + + /** + * Name of the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun name(): Optional = body.name() + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun options(): Optional = body.options() + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun userId(): Optional = body.userId() + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewData(): Optional = body.viewData() + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun viewType(): Optional = body.viewType() + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectId(): JsonField = body._objectId() + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _objectType(): JsonField = body._objectType() + + /** + * 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 [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _options(): JsonField = body._options() + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _userId(): JsonField = body._userId() + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewData(): JsonField = body._viewData() + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _viewType(): JsonField = body._viewType() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + fun _additionalHeaders(): Headers = additionalHeaders + + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + @JvmSynthetic internal fun _body(): Body = body + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams fun getPathParam(index: Int): String { return when (index) { @@ -74,543 +163,805 @@ constructor( } } - @JsonDeserialize(builder = ViewUpdateBody.Builder::class) @NoAutoDetect - class ViewUpdateBody - internal constructor( - private val objectId: String?, - private val objectType: ObjectType?, - private val name: String?, - private val options: ViewOptions?, - private val userId: String?, - private val viewData: ViewData?, - private val viewType: ViewType?, - private val additionalProperties: Map, + class Body + @JsonCreator + private constructor( + @JsonProperty("object_id") + @ExcludeMissing + private val objectId: JsonField = JsonMissing.of(), + @JsonProperty("object_type") + @ExcludeMissing + private val objectType: JsonField = JsonMissing.of(), + @JsonProperty("name") + @ExcludeMissing + private val name: JsonField = JsonMissing.of(), + @JsonProperty("options") + @ExcludeMissing + private val options: JsonField = JsonMissing.of(), + @JsonProperty("user_id") + @ExcludeMissing + private val userId: JsonField = JsonMissing.of(), + @JsonProperty("view_data") + @ExcludeMissing + private val viewData: JsonField = JsonMissing.of(), + @JsonProperty("view_type") + @ExcludeMissing + private val viewType: JsonField = JsonMissing.of(), + @JsonAnySetter + private val additionalProperties: Map = immutableEmptyMap(), ) { - private var hashCode: Int = 0 - - /** The id of the object the view applies to */ - @JsonProperty("object_id") fun objectId(): String? = objectId - - /** The object type that the ACL applies to */ - @JsonProperty("object_type") fun objectType(): ObjectType? = objectType - - /** Name of the view */ - @JsonProperty("name") fun name(): String? = name - - /** Options for the view in the app */ - @JsonProperty("options") fun options(): ViewOptions? = options - - /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(): String? = userId - - /** The view definition */ - @JsonProperty("view_data") fun viewData(): ViewData? = viewData - - /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") fun viewType(): ViewType? = viewType + /** + * The id of the object the view applies to + * + * @throws BraintrustInvalidDataException 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 objectId(): String = objectId.getRequired("object_id") + + /** + * The object type that the ACL applies to + * + * @throws BraintrustInvalidDataException 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 objectType(): AclObjectType = objectType.getRequired("object_type") + + /** + * Name of the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = Optional.ofNullable(name.getNullable("name")) + + /** + * Options for the view in the app + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun options(): Optional = Optional.ofNullable(options.getNullable("options")) + + /** + * Identifies the user who created the view + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun userId(): Optional = Optional.ofNullable(userId.getNullable("user_id")) + + /** + * The view definition + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewData(): Optional = Optional.ofNullable(viewData.getNullable("view_data")) + + /** + * Type of table that the view corresponds to. + * + * @throws BraintrustInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun viewType(): Optional = Optional.ofNullable(viewType.getNullable("view_type")) + + /** + * Returns the raw JSON value of [objectId]. + * + * Unlike [objectId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_id") @ExcludeMissing fun _objectId(): JsonField = objectId + + /** + * Returns the raw JSON value of [objectType]. + * + * Unlike [objectType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("object_type") + @ExcludeMissing + fun _objectType(): JsonField = objectType + + /** + * 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 [options]. + * + * Unlike [options], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("options") @ExcludeMissing fun _options(): JsonField = options + + /** + * Returns the raw JSON value of [userId]. + * + * Unlike [userId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("user_id") @ExcludeMissing fun _userId(): JsonField = userId + + /** + * Returns the raw JSON value of [viewData]. + * + * Unlike [viewData], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_data") @ExcludeMissing fun _viewData(): JsonField = viewData + + /** + * Returns the raw JSON value of [viewType]. + * + * Unlike [viewType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("view_type") @ExcludeMissing fun _viewType(): JsonField = viewType @JsonAnyGetter @ExcludeMissing fun _additionalProperties(): Map = additionalProperties - fun toBuilder() = Builder().from(this) + private var validated: Boolean = false - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + fun validate(): Body = apply { + if (validated) { + return@apply } - return other is ViewUpdateBody && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.name == other.name && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.viewType == other.viewType && - this.additionalProperties == other.additionalProperties - } - - override fun hashCode(): Int { - if (hashCode == 0) { - hashCode = - Objects.hash( - objectId, - objectType, - name, - options, - userId, - viewData, - viewType, - additionalProperties, - ) - } - return hashCode + objectId() + objectType() + name() + options().ifPresent { it.validate() } + userId() + viewData().ifPresent { it.validate() } + viewType() + validated = true } - override fun toString() = - "ViewUpdateBody{objectId=$objectId, objectType=$objectType, name=$name, options=$options, userId=$userId, viewData=$viewData, viewType=$viewType, additionalProperties=$additionalProperties}" + fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [Body]. + * + * The following fields are required: + * ```java + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } - class Builder { + /** A builder for [Body]. */ + class Builder internal constructor() { - private var objectId: String? = null - private var objectType: ObjectType? = null - private var name: String? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null - private var viewType: ViewType? = null + private var objectId: JsonField? = null + private var objectType: JsonField? = null + private var name: JsonField = JsonMissing.of() + private var options: JsonField = JsonMissing.of() + private var userId: JsonField = JsonMissing.of() + private var viewData: JsonField = JsonMissing.of() + private var viewType: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(viewUpdateBody: ViewUpdateBody) = apply { - this.objectId = viewUpdateBody.objectId - this.objectType = viewUpdateBody.objectType - this.name = viewUpdateBody.name - this.options = viewUpdateBody.options - this.userId = viewUpdateBody.userId - this.viewData = viewUpdateBody.viewData - this.viewType = viewUpdateBody.viewType - additionalProperties(viewUpdateBody.additionalProperties) + internal fun from(body: Body) = apply { + objectId = body.objectId + objectType = body.objectType + name = body.name + options = body.options + userId = body.userId + viewData = body.viewData + viewType = body.viewType + additionalProperties = body.additionalProperties.toMutableMap() } /** The id of the object the view applies to */ - @JsonProperty("object_id") - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = objectId(JsonField.of(objectId)) + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectId(objectId: JsonField) = apply { this.objectId = objectId } /** The object type that the ACL applies to */ - @JsonProperty("object_type") - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = objectType(JsonField.of(objectType)) + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { + this.objectType = objectType + } /** Name of the view */ - @JsonProperty("name") fun name(name: String) = apply { this.name = name } + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * 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 } /** Options for the view in the app */ - @JsonProperty("options") - fun options(options: ViewOptions) = apply { this.options = options } + fun options(options: ViewOptions?) = options(JsonField.ofNullable(options)) + + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) + + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun options(options: JsonField) = apply { this.options = options } /** Identifies the user who created the view */ - @JsonProperty("user_id") fun userId(userId: String) = apply { this.userId = userId } + fun userId(userId: String?) = userId(JsonField.ofNullable(userId)) + + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) + + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun userId(userId: JsonField) = apply { this.userId = userId } /** The view definition */ - @JsonProperty("view_data") - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + fun viewData(viewData: ViewData?) = viewData(JsonField.ofNullable(viewData)) + + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) + + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewData(viewData: JsonField) = apply { this.viewData = viewData } /** Type of table that the view corresponds to. */ - @JsonProperty("view_type") - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + fun viewType(viewType: ViewType?) = viewType(JsonField.ofNullable(viewType)) + + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) + + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun viewType(viewType: JsonField) = apply { this.viewType = viewType } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() - this.additionalProperties.putAll(additionalProperties) + putAllAdditionalProperties(additionalProperties) } - @JsonAnySetter fun putAdditionalProperty(key: String, value: JsonValue) = apply { - this.additionalProperties.put(key, value) + additionalProperties.put(key, value) } fun putAllAdditionalProperties(additionalProperties: Map) = apply { this.additionalProperties.putAll(additionalProperties) } - fun build(): ViewUpdateBody = - ViewUpdateBody( - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, + 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 + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Body = + Body( + checkRequired("objectId", objectId), + checkRequired("objectType", objectType), name, options, userId, viewData, viewType, - additionalProperties.toUnmodifiable(), + additionalProperties.toImmutable(), ) } - } - - fun _additionalQueryParams(): Map> = additionalQueryParams - - fun _additionalHeaders(): Map> = additionalHeaders - fun _additionalBodyProperties(): Map = additionalBodyProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + return /* spotless:off */ other is Body && objectId == other.objectId && objectType == other.objectType && name == other.name && options == other.options && userId == other.userId && viewData == other.viewData && viewType == other.viewType && additionalProperties == other.additionalProperties /* spotless:on */ } - return other is ViewUpdateParams && - this.viewId == other.viewId && - this.objectId == other.objectId && - this.objectType == other.objectType && - this.name == other.name && - this.options == other.options && - this.userId == other.userId && - this.viewData == other.viewData && - this.viewType == other.viewType && - this.additionalQueryParams == other.additionalQueryParams && - this.additionalHeaders == other.additionalHeaders && - this.additionalBodyProperties == other.additionalBodyProperties - } + /* spotless:off */ + private val hashCode: Int by lazy { Objects.hash(objectId, objectType, name, options, userId, viewData, viewType, additionalProperties) } + /* spotless:on */ - override fun hashCode(): Int { - return Objects.hash( - viewId, - objectId, - objectType, - name, - options, - userId, - viewData, - viewType, - additionalQueryParams, - additionalHeaders, - additionalBodyProperties, - ) - } + override fun hashCode(): Int = hashCode - override fun toString() = - "ViewUpdateParams{viewId=$viewId, objectId=$objectId, objectType=$objectType, name=$name, options=$options, userId=$userId, viewData=$viewData, viewType=$viewType, additionalQueryParams=$additionalQueryParams, additionalHeaders=$additionalHeaders, additionalBodyProperties=$additionalBodyProperties}" + override fun toString() = + "Body{objectId=$objectId, objectType=$objectType, name=$name, options=$options, userId=$userId, viewData=$viewData, viewType=$viewType, additionalProperties=$additionalProperties}" + } fun toBuilder() = Builder().from(this) companion object { + /** + * Returns a mutable builder for constructing an instance of [ViewUpdateParams]. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + */ @JvmStatic fun builder() = Builder() } + /** A builder for [ViewUpdateParams]. */ @NoAutoDetect - class Builder { + class Builder internal constructor() { private var viewId: String? = null - private var objectId: String? = null - private var objectType: ObjectType? = null - private var name: String? = null - private var options: ViewOptions? = null - private var userId: String? = null - private var viewData: ViewData? = null - private var viewType: ViewType? = null - private var additionalQueryParams: MutableMap> = mutableMapOf() - private var additionalHeaders: MutableMap> = mutableMapOf() - private var additionalBodyProperties: MutableMap = mutableMapOf() + 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(viewUpdateParams: ViewUpdateParams) = apply { - this.viewId = viewUpdateParams.viewId - this.objectId = viewUpdateParams.objectId - this.objectType = viewUpdateParams.objectType - this.name = viewUpdateParams.name - this.options = viewUpdateParams.options - this.userId = viewUpdateParams.userId - this.viewData = viewUpdateParams.viewData - this.viewType = viewUpdateParams.viewType - additionalQueryParams(viewUpdateParams.additionalQueryParams) - additionalHeaders(viewUpdateParams.additionalHeaders) - additionalBodyProperties(viewUpdateParams.additionalBodyProperties) + viewId = viewUpdateParams.viewId + body = viewUpdateParams.body.toBuilder() + additionalHeaders = viewUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = viewUpdateParams.additionalQueryParams.toBuilder() } /** View id */ fun viewId(viewId: String) = apply { this.viewId = viewId } /** The id of the object the view applies to */ - fun objectId(objectId: String) = apply { this.objectId = objectId } + fun objectId(objectId: String) = apply { body.objectId(objectId) } + + /** + * Sets [Builder.objectId] to an arbitrary JSON value. + * + * You should usually call [Builder.objectId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun objectId(objectId: JsonField) = apply { body.objectId(objectId) } /** The object type that the ACL applies to */ - fun objectType(objectType: ObjectType) = apply { this.objectType = objectType } + fun objectType(objectType: AclObjectType) = apply { body.objectType(objectType) } + + /** + * Sets [Builder.objectType] to an arbitrary JSON value. + * + * You should usually call [Builder.objectType] with a well-typed [AclObjectType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun objectType(objectType: JsonField) = apply { body.objectType(objectType) } /** Name of the view */ - fun name(name: String) = apply { this.name = name } + fun name(name: String?) = apply { body.name(name) } - /** Options for the view in the app */ - fun options(options: ViewOptions) = apply { this.options = options } + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) - /** Identifies the user who created the view */ - fun userId(userId: String) = apply { this.userId = userId } + /** + * 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) } - /** The view definition */ - fun viewData(viewData: ViewData) = apply { this.viewData = viewData } + /** Options for the view in the app */ + fun options(options: ViewOptions?) = apply { body.options(options) } - /** Type of table that the view corresponds to. */ - fun viewType(viewType: ViewType) = apply { this.viewType = viewType } + /** Alias for calling [Builder.options] with `options.orElse(null)`. */ + fun options(options: Optional) = options(options.getOrNull()) - fun additionalQueryParams(additionalQueryParams: Map>) = apply { - this.additionalQueryParams.clear() - putAllQueryParams(additionalQueryParams) - } + /** + * Sets [Builder.options] to an arbitrary JSON value. + * + * You should usually call [Builder.options] with a well-typed [ViewOptions] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun options(options: JsonField) = apply { body.options(options) } - fun putQueryParam(name: String, value: String) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.add(value) - } + /** Identifies the user who created the view */ + fun userId(userId: String?) = apply { body.userId(userId) } - fun putQueryParams(name: String, values: Iterable) = apply { - this.additionalQueryParams.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** Alias for calling [Builder.userId] with `userId.orElse(null)`. */ + fun userId(userId: Optional) = userId(userId.getOrNull()) - fun putAllQueryParams(additionalQueryParams: Map>) = apply { - additionalQueryParams.forEach(this::putQueryParams) - } + /** + * Sets [Builder.userId] to an arbitrary JSON value. + * + * You should usually call [Builder.userId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun userId(userId: JsonField) = apply { body.userId(userId) } - fun removeQueryParam(name: String) = apply { - this.additionalQueryParams.put(name, mutableListOf()) - } + /** The view definition */ + fun viewData(viewData: ViewData?) = apply { body.viewData(viewData) } - fun additionalHeaders(additionalHeaders: Map>) = apply { - this.additionalHeaders.clear() - putAllHeaders(additionalHeaders) - } + /** Alias for calling [Builder.viewData] with `viewData.orElse(null)`. */ + fun viewData(viewData: Optional) = viewData(viewData.getOrNull()) - fun putHeader(name: String, value: String) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.add(value) - } + /** + * Sets [Builder.viewData] to an arbitrary JSON value. + * + * You should usually call [Builder.viewData] with a well-typed [ViewData] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewData(viewData: JsonField) = apply { body.viewData(viewData) } - fun putHeaders(name: String, values: Iterable) = apply { - this.additionalHeaders.getOrPut(name) { mutableListOf() }.addAll(values) - } + /** Type of table that the view corresponds to. */ + fun viewType(viewType: ViewType?) = apply { body.viewType(viewType) } - fun putAllHeaders(additionalHeaders: Map>) = apply { - additionalHeaders.forEach(this::putHeaders) - } + /** Alias for calling [Builder.viewType] with `viewType.orElse(null)`. */ + fun viewType(viewType: Optional) = viewType(viewType.getOrNull()) - fun removeHeader(name: String) = apply { this.additionalHeaders.put(name, mutableListOf()) } + /** + * Sets [Builder.viewType] to an arbitrary JSON value. + * + * You should usually call [Builder.viewType] with a well-typed [ViewType] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun viewType(viewType: JsonField) = apply { body.viewType(viewType) } fun additionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.clear() - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.additionalProperties(additionalBodyProperties) } fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { - this.additionalBodyProperties.put(key, value) + body.putAdditionalProperty(key, value) } fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = apply { - this.additionalBodyProperties.putAll(additionalBodyProperties) + body.putAllAdditionalProperties(additionalBodyProperties) } - fun build(): ViewUpdateParams = - ViewUpdateParams( - checkNotNull(viewId) { "`viewId` is required but was not set" }, - checkNotNull(objectId) { "`objectId` is required but was not set" }, - checkNotNull(objectType) { "`objectType` is required but was not set" }, - name, - options, - userId, - viewData, - viewType, - additionalQueryParams.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalHeaders.mapValues { it.value.toUnmodifiable() }.toUnmodifiable(), - additionalBodyProperties.toUnmodifiable(), - ) - } + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } - class ObjectType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } - return other is ObjectType && this.value == other.value + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) } - override fun hashCode() = value.hashCode() + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } - override fun toString() = value.toString() + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } - companion object { + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } - @JvmField val ORGANIZATION = ObjectType(JsonField.of("organization")) + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } - @JvmField val PROJECT = ObjectType(JsonField.of("project")) + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val EXPERIMENT = ObjectType(JsonField.of("experiment")) + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } - @JvmField val DATASET = ObjectType(JsonField.of("dataset")) + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } - @JvmField val PROMPT = ObjectType(JsonField.of("prompt")) + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } - @JvmField val PROMPT_SESSION = ObjectType(JsonField.of("prompt_session")) + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val GROUP = ObjectType(JsonField.of("group")) + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } - @JvmField val ROLE = ObjectType(JsonField.of("role")) + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } - @JvmField val ORG_MEMBER = ObjectType(JsonField.of("org_member")) + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } - @JvmField val PROJECT_LOG = ObjectType(JsonField.of("project_log")) + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmField val ORG_PROJECT = ObjectType(JsonField.of("org_project")) + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } - @JvmStatic fun of(value: String) = ObjectType(JsonField.of(value)) + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) } - enum class Known { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) } - enum class Value { - ORGANIZATION, - PROJECT, - EXPERIMENT, - DATASET, - PROMPT, - PROMPT_SESSION, - GROUP, - ROLE, - ORG_MEMBER, - PROJECT_LOG, - ORG_PROJECT, - _UNKNOWN, + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun value(): Value = - when (this) { - ORGANIZATION -> Value.ORGANIZATION - PROJECT -> Value.PROJECT - EXPERIMENT -> Value.EXPERIMENT - DATASET -> Value.DATASET - PROMPT -> Value.PROMPT - PROMPT_SESSION -> Value.PROMPT_SESSION - GROUP -> Value.GROUP - ROLE -> Value.ROLE - ORG_MEMBER -> Value.ORG_MEMBER - PROJECT_LOG -> Value.PROJECT_LOG - ORG_PROJECT -> Value.ORG_PROJECT - else -> Value._UNKNOWN + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) } - fun known(): Known = - when (this) { - ORGANIZATION -> Known.ORGANIZATION - PROJECT -> Known.PROJECT - EXPERIMENT -> Known.EXPERIMENT - DATASET -> Known.DATASET - PROMPT -> Known.PROMPT - PROMPT_SESSION -> Known.PROMPT_SESSION - GROUP -> Known.GROUP - ROLE -> Known.ROLE - ORG_MEMBER -> Known.ORG_MEMBER - PROJECT_LOG -> Known.PROJECT_LOG - ORG_PROJECT -> Known.ORG_PROJECT - else -> throw BraintrustInvalidDataException("Unknown ObjectType: $value") - } + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } - fun asString(): String = _value().asStringOrThrow() - } + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } - class ViewType - @JsonCreator - private constructor( - private val value: JsonField, - ) : Enum { + /** + * Returns an immutable instance of [ViewUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .viewId() + * .objectId() + * .objectType() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ViewUpdateParams = + ViewUpdateParams( + checkRequired("viewId", viewId), + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + /** Type of table that the view corresponds to. */ + class ViewType @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 - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + companion object { - return other is ViewType && this.value == other.value - } + @JvmField val PROJECTS = of("projects") - override fun hashCode() = value.hashCode() + @JvmField val EXPERIMENTS = of("experiments") - override fun toString() = value.toString() + @JvmField val EXPERIMENT = of("experiment") - companion object { + @JvmField val PLAYGROUNDS = of("playgrounds") - @JvmField val PROJECTS = ViewType(JsonField.of("projects")) + @JvmField val PLAYGROUND = of("playground") - @JvmField val LOGS = ViewType(JsonField.of("logs")) + @JvmField val DATASETS = of("datasets") - @JvmField val EXPERIMENTS = ViewType(JsonField.of("experiments")) + @JvmField val DATASET = of("dataset") - @JvmField val DATASETS = ViewType(JsonField.of("datasets")) + @JvmField val PROMPTS = of("prompts") - @JvmField val PROMPTS = ViewType(JsonField.of("prompts")) + @JvmField val TOOLS = of("tools") - @JvmField val PLAYGROUNDS = ViewType(JsonField.of("playgrounds")) + @JvmField val SCORERS = of("scorers") - @JvmField val EXPERIMENT = ViewType(JsonField.of("experiment")) - - @JvmField val DATASET = ViewType(JsonField.of("dataset")) + @JvmField val LOGS = of("logs") @JvmStatic fun of(value: String) = ViewType(JsonField.of(value)) } + /** An enum containing [ViewType]'s known values. */ enum class Known { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, } + /** + * An enum containing [ViewType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ViewType] 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 { PROJECTS, - LOGS, EXPERIMENTS, - DATASETS, - PROMPTS, - PLAYGROUNDS, EXPERIMENT, + PLAYGROUNDS, + PLAYGROUND, + DATASETS, DATASET, + PROMPTS, + TOOLS, + SCORERS, + LOGS, + /** An enum member indicating that [ViewType] 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) { PROJECTS -> Value.PROJECTS - LOGS -> Value.LOGS EXPERIMENTS -> Value.EXPERIMENTS - DATASETS -> Value.DATASETS - PROMPTS -> Value.PROMPTS - PLAYGROUNDS -> Value.PLAYGROUNDS EXPERIMENT -> Value.EXPERIMENT + PLAYGROUNDS -> Value.PLAYGROUNDS + PLAYGROUND -> Value.PLAYGROUND + DATASETS -> Value.DATASETS DATASET -> Value.DATASET + PROMPTS -> Value.PROMPTS + TOOLS -> Value.TOOLS + SCORERS -> Value.SCORERS + LOGS -> Value.LOGS 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 BraintrustInvalidDataException if this class instance's value is a not a known + * member. + */ fun known(): Known = when (this) { PROJECTS -> Known.PROJECTS - LOGS -> Known.LOGS EXPERIMENTS -> Known.EXPERIMENTS - DATASETS -> Known.DATASETS - PROMPTS -> Known.PROMPTS - PLAYGROUNDS -> Known.PLAYGROUNDS EXPERIMENT -> Known.EXPERIMENT + PLAYGROUNDS -> Known.PLAYGROUNDS + PLAYGROUND -> Known.PLAYGROUND + DATASETS -> Known.DATASETS DATASET -> Known.DATASET + PROMPTS -> Known.PROMPTS + TOOLS -> Known.TOOLS + SCORERS -> Known.SCORERS + LOGS -> Known.LOGS else -> throw BraintrustInvalidDataException("Unknown ViewType: $value") } - fun asString(): String = _value().asStringOrThrow() + /** + * 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 BraintrustInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + BraintrustInvalidDataException("Value is not a String") + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewType && value == other.value /* spotless:on */ + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return /* spotless:off */ other is ViewUpdateParams && viewId == other.viewId && body == other.body && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */ + } + + override fun hashCode(): Int = /* spotless:off */ Objects.hash(viewId, body, additionalHeaders, additionalQueryParams) /* spotless:on */ + + override fun toString() = + "ViewUpdateParams{viewId=$viewId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/HttpRequestBodies.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/HttpRequestBodies.kt deleted file mode 100755 index 4312ec38..00000000 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/HttpRequestBodies.kt +++ /dev/null @@ -1,114 +0,0 @@ -@file:JvmName("HttpRequestBodies") - -package com.braintrustdata.api.services - -import com.braintrustdata.api.core.Enum -import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.MultipartFormValue -import com.braintrustdata.api.core.http.HttpRequestBody -import com.braintrustdata.api.errors.BraintrustException -import com.fasterxml.jackson.databind.json.JsonMapper -import java.io.ByteArrayOutputStream -import java.io.OutputStream -import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder - -@JvmSynthetic -internal inline fun json( - jsonMapper: JsonMapper, - value: T, -): HttpRequestBody { - return object : HttpRequestBody { - private var cachedBytes: ByteArray? = null - - private fun serialize(): ByteArray { - if (cachedBytes != null) return cachedBytes!! - - val buffer = ByteArrayOutputStream() - try { - jsonMapper.writeValue(buffer, value) - cachedBytes = buffer.toByteArray() - return cachedBytes!! - } catch (e: Exception) { - throw BraintrustException("Error writing request", e) - } - } - - override fun writeTo(outputStream: OutputStream) { - outputStream.write(serialize()) - } - - override fun contentType(): String = "application/json" - - override fun contentLength(): Long { - return serialize().size.toLong() - } - - override fun repeatable(): Boolean = true - - override fun close() {} - } -} - -@JvmSynthetic -internal fun multipartFormData( - jsonMapper: JsonMapper, - parts: Array?> -): HttpRequestBody { - val builder = MultipartEntityBuilder.create() - parts.forEach { part -> - if (part?.value != null) { - when (part.value) { - is JsonValue -> { - val buffer = ByteArrayOutputStream() - try { - jsonMapper.writeValue(buffer, part.value) - } catch (e: Exception) { - throw BraintrustException("Error serializing value to json", e) - } - builder.addBinaryBody( - part.name, - buffer.toByteArray(), - part.contentType, - part.filename - ) - } - is Boolean -> - builder.addTextBody( - part.name, - if (part.value) "true" else "false", - part.contentType - ) - is Int -> builder.addTextBody(part.name, part.value.toString(), part.contentType) - is Long -> builder.addTextBody(part.name, part.value.toString(), part.contentType) - is Double -> builder.addTextBody(part.name, part.value.toString(), part.contentType) - is ByteArray -> - builder.addBinaryBody(part.name, part.value, part.contentType, part.filename) - is String -> builder.addTextBody(part.name, part.value, part.contentType) - is Enum -> builder.addTextBody(part.name, part.value.toString(), part.contentType) - else -> - throw IllegalArgumentException( - "Unsupported content type: ${part.value::class.java.simpleName}" - ) - } - } - } - val entity = builder.build() - - return object : HttpRequestBody { - override fun writeTo(outputStream: OutputStream) { - try { - return entity.writeTo(outputStream) - } catch (e: Exception) { - throw BraintrustException("Error writing request", e) - } - } - - override fun contentType(): String = entity.contentType - - override fun contentLength(): Long = -1 - - override fun repeatable(): Boolean = entity.isRepeatable - - override fun close() = entity.close() - } -} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsync.kt index 29a5433d..a1688232 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Acl import com.braintrustdata.api.models.AclBatchUpdateParams import com.braintrustdata.api.models.AclBatchUpdateResponse @@ -14,58 +13,199 @@ import com.braintrustdata.api.models.AclFindAndDeleteParams import com.braintrustdata.api.models.AclListPageAsync import com.braintrustdata.api.models.AclListParams import com.braintrustdata.api.models.AclRetrieveParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface AclServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new acl. If there is an existing acl with the same contents as the one specified in * the request, will return the existing acl unmodified */ - @JvmOverloads + fun create(params: AclCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: AclCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get an acl object by its id */ - @JvmOverloads + fun retrieve(params: AclRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: AclRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all acls. The acls are sorted by creation date, with the most recently-created acls * coming first */ - @JvmOverloads + fun list(params: AclListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ fun list( params: AclListParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Delete an acl object by its id */ - @JvmOverloads + fun delete(params: AclDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: AclDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Batch update acls. This operation is idempotent, so adding acls which already exist will have * no effect, and removing acls which do not exist will have no effect. */ - @JvmOverloads + fun batchUpdate(): CompletableFuture = + batchUpdate(AclBatchUpdateParams.none()) + + /** @see [batchUpdate] */ fun batchUpdate( - params: AclBatchUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + params: AclBatchUpdateParams = AclBatchUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [batchUpdate] */ + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none() + ): CompletableFuture = batchUpdate(params, RequestOptions.none()) + + /** @see [batchUpdate] */ + fun batchUpdate(requestOptions: RequestOptions): CompletableFuture = + batchUpdate(AclBatchUpdateParams.none(), requestOptions) + /** Delete a single acl */ - @JvmOverloads + fun findAndDelete(params: AclFindAndDeleteParams): CompletableFuture = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ fun findAndDelete( params: AclFindAndDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [AclServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/acl`, but is otherwise the same as + * [AclServiceAsync.create]. + */ + @MustBeClosed + fun create(params: AclCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: AclCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/acl/{acl_id}`, but is otherwise the same as + * [AclServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: AclRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: AclRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/acl`, but is otherwise the same as + * [AclServiceAsync.list]. + */ + @MustBeClosed + fun list(params: AclListParams): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: AclListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `delete /v1/acl/{acl_id}`, but is otherwise the same as + * [AclServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: AclDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: AclDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/acl/batch_update`, but is otherwise the same as + * [AclServiceAsync.batchUpdate]. + */ + @MustBeClosed + fun batchUpdate(): CompletableFuture> = + batchUpdate(AclBatchUpdateParams.none()) + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none() + ): CompletableFuture> = + batchUpdate(params, RequestOptions.none()) + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate( + requestOptions: RequestOptions + ): CompletableFuture> = + batchUpdate(AclBatchUpdateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/acl`, but is otherwise the same as + * [AclServiceAsync.findAndDelete]. + */ + @MustBeClosed + fun findAndDelete(params: AclFindAndDeleteParams): CompletableFuture> = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ + @MustBeClosed + fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncImpl.kt index 41c071d5..ab68729d 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Acl import com.braintrustdata.api.models.AclBatchUpdateParams @@ -17,203 +24,243 @@ import com.braintrustdata.api.models.AclFindAndDeleteParams import com.braintrustdata.api.models.AclListPageAsync import com.braintrustdata.api.models.AclListParams import com.braintrustdata.api.models.AclRetrieveParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class AclServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : AclServiceAsync { +class AclServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + AclServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: AclServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): AclServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new acl. If there is an existing acl with the same contents as the one specified in - * the request, will return the existing acl unmodified - */ override fun create( params: AclCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/acl + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: AclRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/acl/{acl_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: AclListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/acl + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: AclDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/acl/{acl_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun batchUpdate( + params: AclBatchUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/acl/batch_update + withRawResponse().batchUpdate(params, requestOptions).thenApply { it.parse() } + + override fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/acl + withRawResponse().findAndDelete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AclServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: AclCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "acl") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an acl object by its id */ - override fun retrieve( - params: AclRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "acl", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: AclRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "acl", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all acls. The acls are sorted by creation date, with the most recently-created acls - * coming first - */ - override fun list( - params: AclListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: AclListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "acl") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + AclListPageAsync.of(AclServiceAsyncImpl(clientOptions), params, it) + } } } - .let { AclListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an acl object by its id */ - override fun delete( - params: AclDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "acl", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: AclDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "acl", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val batchUpdateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val batchUpdateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Batch update acls. This operation is idempotent, so adding acls which already exist will have - * no effect, and removing acls which do not exist will have no effect. - */ - override fun batchUpdate( - params: AclBatchUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "acl", "batch-update") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { batchUpdateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun batchUpdate( + params: AclBatchUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "acl", "batch_update") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { batchUpdateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val findAndDeleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val findAndDeleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a single acl */ - override fun findAndDelete( - params: AclFindAndDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { findAndDeleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "acl") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { findAndDeleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsync.kt index ff2feb19..dc90a38c 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.AISecret import com.braintrustdata.api.models.AiSecretCreateParams import com.braintrustdata.api.models.AiSecretDeleteParams @@ -14,25 +13,37 @@ import com.braintrustdata.api.models.AiSecretListParams import com.braintrustdata.api.models.AiSecretReplaceParams import com.braintrustdata.api.models.AiSecretRetrieveParams import com.braintrustdata.api.models.AiSecretUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface AiSecretServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new ai_secret. If there is an existing ai_secret with the same name as the one * specified in the request, will return the existing ai_secret unmodified */ - @JvmOverloads + fun create(params: AiSecretCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: AiSecretCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get an ai_secret object by its id */ - @JvmOverloads + fun retrieve(params: AiSecretRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: AiSecretRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -40,43 +51,193 @@ interface AiSecretServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: AiSecretUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: AiSecretUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most * recently-created ai_secrets coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(AiSecretListParams.none()) + + /** @see [list] */ fun list( - params: AiSecretListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: AiSecretListParams = AiSecretListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: AiSecretListParams = AiSecretListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(AiSecretListParams.none(), requestOptions) + /** Delete an ai_secret object by its id */ - @JvmOverloads + fun delete(params: AiSecretDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: AiSecretDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Delete a single ai_secret */ - @JvmOverloads + fun findAndDelete(params: AiSecretFindAndDeleteParams): CompletableFuture = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ fun findAndDelete( params: AiSecretFindAndDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace ai_secret. If there is an existing ai_secret with the same name as the one * specified in the request, will replace the existing ai_secret with the provided fields */ - @JvmOverloads + fun replace(params: AiSecretReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: AiSecretReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [AiSecretServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/ai_secret`, but is otherwise the same as + * [AiSecretServiceAsync.create]. + */ + @MustBeClosed + fun create(params: AiSecretCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: AiSecretCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/ai_secret/{ai_secret_id}`, but is otherwise the + * same as [AiSecretServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: AiSecretRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: AiSecretRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/ai_secret/{ai_secret_id}`, but is otherwise + * the same as [AiSecretServiceAsync.update]. + */ + @MustBeClosed + fun update(params: AiSecretUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: AiSecretUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/ai_secret`, but is otherwise the same as + * [AiSecretServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(AiSecretListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: AiSecretListParams = AiSecretListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: AiSecretListParams = AiSecretListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(AiSecretListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/ai_secret/{ai_secret_id}`, but is otherwise + * the same as [AiSecretServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: AiSecretDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: AiSecretDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `delete /v1/ai_secret`, but is otherwise the same as + * [AiSecretServiceAsync.findAndDelete]. + */ + @MustBeClosed + fun findAndDelete( + params: AiSecretFindAndDeleteParams + ): CompletableFuture> = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ + @MustBeClosed + fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/ai_secret`, but is otherwise the same as + * [AiSecretServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: AiSecretReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: AiSecretReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncImpl.kt index 330c772b..fbe03e82 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.AISecret import com.braintrustdata.api.models.AiSecretCreateParams @@ -17,237 +24,283 @@ import com.braintrustdata.api.models.AiSecretListParams import com.braintrustdata.api.models.AiSecretReplaceParams import com.braintrustdata.api.models.AiSecretRetrieveParams import com.braintrustdata.api.models.AiSecretUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class AiSecretServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : AiSecretServiceAsync { +class AiSecretServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + AiSecretServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: AiSecretServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): AiSecretServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new ai_secret. If there is an existing ai_secret with the same name as the one - * specified in the request, will return the existing ai_secret unmodified - */ override fun create( params: AiSecretCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/ai_secret + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: AiSecretRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/ai_secret/{ai_secret_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: AiSecretUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/ai_secret/{ai_secret_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: AiSecretListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/ai_secret + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: AiSecretDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/ai_secret/{ai_secret_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/ai_secret + withRawResponse().findAndDelete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: AiSecretReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/ai_secret + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AiSecretServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: AiSecretCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an ai_secret object by its id */ - override fun retrieve( - params: AiSecretRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: AiSecretRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an ai_secret object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: AiSecretUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: AiSecretUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most - * recently-created ai_secrets coming first - */ - override fun list( - params: AiSecretListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: AiSecretListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "ai_secret") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + AiSecretListPageAsync.of( + AiSecretServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { AiSecretListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an ai_secret object by its id */ - override fun delete( - params: AiSecretDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: AiSecretDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val findAndDeleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val findAndDeleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a single ai_secret */ - override fun findAndDelete( - params: AiSecretFindAndDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { findAndDeleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { findAndDeleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace ai_secret. If there is an existing ai_secret with the same name as the one - * specified in the request, will replace the existing ai_secret with the provided fields - */ - override fun replace( - params: AiSecretReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: AiSecretReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsync.kt index 3dab4049..94e69910 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ApiKey import com.braintrustdata.api.models.ApiKeyCreateParams import com.braintrustdata.api.models.ApiKeyDeleteParams @@ -12,41 +11,149 @@ import com.braintrustdata.api.models.ApiKeyListPageAsync import com.braintrustdata.api.models.ApiKeyListParams import com.braintrustdata.api.models.ApiKeyRetrieveParams import com.braintrustdata.api.models.CreateApiKeyOutput +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ApiKeyServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new api_key. It is possible to have multiple API keys with the same name. There is * no de-duplication */ - @JvmOverloads + fun create(params: ApiKeyCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ApiKeyCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get an api_key object by its id */ - @JvmOverloads + fun retrieve(params: ApiKeyRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ApiKeyRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all api_keys. The api_keys are sorted by creation date, with the most * recently-created api_keys coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(ApiKeyListParams.none()) + + /** @see [list] */ fun list( - params: ApiKeyListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ApiKeyListParams = ApiKeyListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: ApiKeyListParams = ApiKeyListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(ApiKeyListParams.none(), requestOptions) + /** Delete an api_key object by its id */ - @JvmOverloads + fun delete(params: ApiKeyDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ApiKeyDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [ApiKeyServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/api_key`, but is otherwise the same as + * [ApiKeyServiceAsync.create]. + */ + @MustBeClosed + fun create( + params: ApiKeyCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ApiKeyCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/api_key/{api_key_id}`, but is otherwise the same + * as [ApiKeyServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ApiKeyRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ApiKeyRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/api_key`, but is otherwise the same as + * [ApiKeyServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(ApiKeyListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ApiKeyListParams = ApiKeyListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: ApiKeyListParams = ApiKeyListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(ApiKeyListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/api_key/{api_key_id}`, but is otherwise the + * same as [ApiKeyServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: ApiKeyDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ApiKeyDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncImpl.kt index 5228efa4..ca00a3e4 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ApiKey import com.braintrustdata.api.models.ApiKeyCreateParams @@ -15,140 +22,172 @@ import com.braintrustdata.api.models.ApiKeyListPageAsync import com.braintrustdata.api.models.ApiKeyListParams import com.braintrustdata.api.models.ApiKeyRetrieveParams import com.braintrustdata.api.models.CreateApiKeyOutput -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ApiKeyServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ApiKeyServiceAsync { +class ApiKeyServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ApiKeyServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ApiKeyServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ApiKeyServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new api_key. It is possible to have multiple API keys with the same name. There is - * no de-duplication - */ override fun create( params: ApiKeyCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "api_key") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/api_key + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: ApiKeyRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/api_key/{api_key_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ApiKeyListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/api_key + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ApiKeyDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/api_key/{api_key_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ApiKeyServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ApiKeyCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "api_key") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an api_key object by its id */ - override fun retrieve( - params: ApiKeyRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "api_key", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ApiKeyRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "api_key", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all api_keys. The api_keys are sorted by creation date, with the most - * recently-created api_keys coming first - */ - override fun list( - params: ApiKeyListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "api_key") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ApiKeyListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "api_key") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ApiKeyListPageAsync.of( + ApiKeyServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { ApiKeyListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an api_key object by its id */ - override fun delete( - params: ApiKeyDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "api_key", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ApiKeyDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "api_key", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsync.kt index 730918fa..a6d7c52c 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Dataset import com.braintrustdata.api.models.DatasetCreateParams import com.braintrustdata.api.models.DatasetDeleteParams @@ -21,25 +20,37 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchDatasetEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeDatasetResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface DatasetServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new dataset. If there is an existing dataset in the project with the same name as * the one specified in the request, will return the existing dataset unmodified */ - @JvmOverloads + fun create(params: DatasetCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: DatasetCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a dataset object by its id */ - @JvmOverloads + fun retrieve(params: DatasetRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: DatasetRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -47,67 +58,281 @@ interface DatasetServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: DatasetUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: DatasetUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all datasets. The datasets are sorted by creation date, with the most * recently-created datasets coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(DatasetListParams.none()) + + /** @see [list] */ fun list( - params: DatasetListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: DatasetListParams = DatasetListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: DatasetListParams = DatasetListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(DatasetListParams.none(), requestOptions) + /** Delete a dataset object by its id */ - @JvmOverloads + fun delete(params: DatasetDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: DatasetDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Log feedback for a set of dataset events */ - @JvmOverloads + fun feedback(params: DatasetFeedbackParams): CompletableFuture = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: DatasetFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in a dataset. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body + * parameters in the URL query rather than in the request body. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: DatasetFetchParams): CompletableFuture = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: DatasetFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in a dataset. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost(params: DatasetFetchPostParams): CompletableFuture = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: DatasetFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Insert a set of events into the dataset */ - @JvmOverloads + fun insert(params: DatasetInsertParams): CompletableFuture = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: DatasetInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Summarize dataset */ - @JvmOverloads + fun summarize(params: DatasetSummarizeParams): CompletableFuture = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ fun summarize( params: DatasetSummarizeParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [DatasetServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/dataset`, but is otherwise the same as + * [DatasetServiceAsync.create]. + */ + @MustBeClosed + fun create(params: DatasetCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: DatasetCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}`, but is otherwise the same + * as [DatasetServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: DatasetRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: DatasetRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/dataset/{dataset_id}`, but is otherwise the + * same as [DatasetServiceAsync.update]. + */ + @MustBeClosed + fun update(params: DatasetUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: DatasetUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/dataset`, but is otherwise the same as + * [DatasetServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(DatasetListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: DatasetListParams = DatasetListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: DatasetListParams = DatasetListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(DatasetListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/dataset/{dataset_id}`, but is otherwise the + * same as [DatasetServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: DatasetDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: DatasetDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/feedback`, but is + * otherwise the same as [DatasetServiceAsync.feedback]. + */ + @MustBeClosed + fun feedback( + params: DatasetFeedbackParams + ): CompletableFuture> = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}/fetch`, but is otherwise + * the same as [DatasetServiceAsync.fetch]. + */ + @MustBeClosed + fun fetch( + params: DatasetFetchParams + ): CompletableFuture> = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/fetch`, but is otherwise + * the same as [DatasetServiceAsync.fetchPost]. + */ + @MustBeClosed + fun fetchPost( + params: DatasetFetchPostParams + ): CompletableFuture> = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/insert`, but is otherwise + * the same as [DatasetServiceAsync.insert]. + */ + @MustBeClosed + fun insert( + params: DatasetInsertParams + ): CompletableFuture> = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}/summarize`, but is + * otherwise the same as [DatasetServiceAsync.summarize]. + */ + @MustBeClosed + fun summarize( + params: DatasetSummarizeParams + ): CompletableFuture> = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ + @MustBeClosed + fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncImpl.kt index 7430668e..7a5002f9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Dataset import com.braintrustdata.api.models.DatasetCreateParams @@ -24,331 +31,397 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchDatasetEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeDatasetResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class DatasetServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : DatasetServiceAsync { +class DatasetServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + DatasetServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: DatasetServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): DatasetServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new dataset. If there is an existing dataset in the project with the same name as - * the one specified in the request, will return the existing dataset unmodified - */ override fun create( params: DatasetCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/dataset + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: DatasetRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/dataset/{dataset_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: DatasetUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/dataset/{dataset_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: DatasetListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/dataset + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: DatasetDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/dataset/{dataset_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/dataset/{dataset_id}/feedback + withRawResponse().feedback(params, requestOptions).thenApply { it.parse() } + + override fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/dataset/{dataset_id}/fetch + withRawResponse().fetch(params, requestOptions).thenApply { it.parse() } + + override fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/dataset/{dataset_id}/fetch + withRawResponse().fetchPost(params, requestOptions).thenApply { it.parse() } + + override fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/dataset/{dataset_id}/insert + withRawResponse().insert(params, requestOptions).thenApply { it.parse() } + + override fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/dataset/{dataset_id}/summarize + withRawResponse().summarize(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + DatasetServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: DatasetCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a dataset object by its id */ - override fun retrieve( - params: DatasetRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: DatasetRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a dataset object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: DatasetUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: DatasetUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all datasets. The datasets are sorted by creation date, with the most - * recently-created datasets coming first - */ - override fun list( - params: DatasetListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: DatasetListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + DatasetListPageAsync.of( + DatasetServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { DatasetListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a dataset object by its id */ - override fun delete( - params: DatasetDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: DatasetDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Log feedback for a set of dataset events */ - override fun feedback( - params: DatasetFeedbackParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a dataset. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body - */ - override fun fetch( - params: DatasetFetchParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a dataset. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: DatasetFetchPostParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the dataset */ - override fun insert( - params: DatasetInsertParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val summarizeHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val summarizeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Summarize dataset */ - override fun summarize( - params: DatasetSummarizeParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0), "summarize") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { summarizeHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0), "summarize") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { summarizeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsync.kt index 5edf3e15..49a3693f 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.EnvVar import com.braintrustdata.api.models.EnvVarCreateParams import com.braintrustdata.api.models.EnvVarDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.EnvVarListResponse import com.braintrustdata.api.models.EnvVarReplaceParams import com.braintrustdata.api.models.EnvVarRetrieveParams import com.braintrustdata.api.models.EnvVarUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface EnvVarServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new env_var. If there is an existing env_var with the same name as the one specified * in the request, will return the existing env_var unmodified */ - @JvmOverloads + fun create(params: EnvVarCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: EnvVarCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get an env_var object by its id */ - @JvmOverloads + fun retrieve(params: EnvVarRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: EnvVarRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,36 +50,166 @@ interface EnvVarServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: EnvVarUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: EnvVarUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all env_vars. The env_vars are sorted by creation date, with the most * recently-created env_vars coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(EnvVarListParams.none()) + + /** @see [list] */ fun list( - params: EnvVarListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: EnvVarListParams = EnvVarListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: EnvVarListParams = EnvVarListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(EnvVarListParams.none(), requestOptions) + /** Delete an env_var object by its id */ - @JvmOverloads + fun delete(params: EnvVarDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: EnvVarDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace env_var. If there is an existing env_var with the same name as the one * specified in the request, will replace the existing env_var with the provided fields */ - @JvmOverloads + fun replace(params: EnvVarReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: EnvVarReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [EnvVarServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/env_var`, but is otherwise the same as + * [EnvVarServiceAsync.create]. + */ + @MustBeClosed + fun create(params: EnvVarCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: EnvVarCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/env_var/{env_var_id}`, but is otherwise the same + * as [EnvVarServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: EnvVarRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: EnvVarRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/env_var/{env_var_id}`, but is otherwise the + * same as [EnvVarServiceAsync.update]. + */ + @MustBeClosed + fun update(params: EnvVarUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: EnvVarUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/env_var`, but is otherwise the same as + * [EnvVarServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(EnvVarListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: EnvVarListParams = EnvVarListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: EnvVarListParams = EnvVarListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(EnvVarListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/env_var/{env_var_id}`, but is otherwise the + * same as [EnvVarServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: EnvVarDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: EnvVarDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/env_var`, but is otherwise the same as + * [EnvVarServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: EnvVarReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: EnvVarReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncImpl.kt index a2f9d114..c4ed7f35 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.EnvVar import com.braintrustdata.api.models.EnvVarCreateParams @@ -16,205 +23,238 @@ import com.braintrustdata.api.models.EnvVarListResponse import com.braintrustdata.api.models.EnvVarReplaceParams import com.braintrustdata.api.models.EnvVarRetrieveParams import com.braintrustdata.api.models.EnvVarUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class EnvVarServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : EnvVarServiceAsync { +class EnvVarServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + EnvVarServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: EnvVarServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): EnvVarServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new env_var. If there is an existing env_var with the same name as the one specified - * in the request, will return the existing env_var unmodified - */ override fun create( params: EnvVarCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/env_var + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: EnvVarRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/env_var/{env_var_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: EnvVarUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/env_var/{env_var_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: EnvVarListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/env_var + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: EnvVarDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/env_var/{env_var_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: EnvVarReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/env_var + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EnvVarServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: EnvVarCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "env_var") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an env_var object by its id */ - override fun retrieve( - params: EnvVarRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: EnvVarRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an env_var object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: EnvVarUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: EnvVarUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * List out all env_vars. The env_vars are sorted by creation date, with the most - * recently-created env_vars coming first - */ - override fun list( - params: EnvVarListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: EnvVarListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "env_var") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an env_var object by its id */ - override fun delete( - params: EnvVarDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: EnvVarDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace env_var. If there is an existing env_var with the same name as the one - * specified in the request, will replace the existing env_var with the provided fields - */ - override fun replace( - params: EnvVarReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: EnvVarReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "env_var") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsync.kt index 7e172805..69b6f45c 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsync.kt @@ -1,16 +1,21 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.EvalCreateParams import com.braintrustdata.api.models.SummarizeExperimentResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface EvalServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Launch an evaluation. This is the API-equivalent of the `Eval` function that is built into * the Braintrust SDK. In the Eval API, you provide pointers to a dataset, task function, and @@ -18,9 +23,33 @@ interface EvalServiceAsync { * results along with a link to the experiment. To learn more about evals, see the * [Evals guide](https://www.braintrust.dev/docs/guides/evals). */ - @JvmOverloads + fun create(params: EvalCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: EvalCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [EvalServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/eval`, but is otherwise the same as + * [EvalServiceAsync.create]. + */ + @MustBeClosed + fun create( + params: EvalCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: EvalCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncImpl.kt index 275cafcb..d0fc0019 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncImpl.kt @@ -4,57 +4,69 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.EvalCreateParams import com.braintrustdata.api.models.SummarizeExperimentResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class EvalServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : EvalServiceAsync { +class EvalServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + EvalServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: EvalServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + override fun withRawResponse(): EvalServiceAsync.WithRawResponse = withRawResponse - /** - * Launch an evaluation. This is the API-equivalent of the `Eval` function that is built into - * the Braintrust SDK. In the Eval API, you provide pointers to a dataset, task function, and - * scoring functions. The API will then run the evaluation, create an experiment, and return the - * results along with a link to the experiment. To learn more about evals, see the - * [Evals guide](https://www.braintrust.dev/docs/guides/evals). - */ override fun create( params: EvalCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "eval") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/eval + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EvalServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun create( + params: EvalCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "eval") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsync.kt index ab9161c7..e10046e6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Experiment import com.braintrustdata.api.models.ExperimentCreateParams import com.braintrustdata.api.models.ExperimentDeleteParams @@ -21,25 +20,37 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchExperimentEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeExperimentResponse +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ExperimentServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new experiment. If there is an existing experiment in the project with the same name * as the one specified in the request, will return the existing experiment unmodified */ - @JvmOverloads + fun create(params: ExperimentCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ExperimentCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get an experiment object by its id */ - @JvmOverloads + fun retrieve(params: ExperimentRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ExperimentRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -47,67 +58,285 @@ interface ExperimentServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ExperimentUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ExperimentUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all experiments. The experiments are sorted by creation date, with the most * recently-created experiments coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(ExperimentListParams.none()) + + /** @see [list] */ fun list( - params: ExperimentListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ExperimentListParams = ExperimentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: ExperimentListParams = ExperimentListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(ExperimentListParams.none(), requestOptions) + /** Delete an experiment object by its id */ - @JvmOverloads + fun delete(params: ExperimentDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ExperimentDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Log feedback for a set of experiment events */ - @JvmOverloads + fun feedback(params: ExperimentFeedbackParams): CompletableFuture = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: ExperimentFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in an experiment. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body + * parameters in the URL query rather than in the request body. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: ExperimentFetchParams): CompletableFuture = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: ExperimentFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in an experiment. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost( + params: ExperimentFetchPostParams + ): CompletableFuture = fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: ExperimentFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Insert a set of events into the experiment */ - @JvmOverloads + fun insert(params: ExperimentInsertParams): CompletableFuture = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: ExperimentInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Summarize experiment */ - @JvmOverloads + fun summarize( + params: ExperimentSummarizeParams + ): CompletableFuture = summarize(params, RequestOptions.none()) + + /** @see [summarize] */ fun summarize( params: ExperimentSummarizeParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [ExperimentServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/experiment`, but is otherwise the same as + * [ExperimentServiceAsync.create]. + */ + @MustBeClosed + fun create(params: ExperimentCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ExperimentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve( + params: ExperimentRetrieveParams + ): CompletableFuture> = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentServiceAsync.update]. + */ + @MustBeClosed + fun update(params: ExperimentUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/experiment`, but is otherwise the same as + * [ExperimentServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(ExperimentListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ExperimentListParams = ExperimentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: ExperimentListParams = ExperimentListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(ExperimentListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: ExperimentDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/feedback`, but is + * otherwise the same as [ExperimentServiceAsync.feedback]. + */ + @MustBeClosed + fun feedback( + params: ExperimentFeedbackParams + ): CompletableFuture> = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}/fetch`, but is + * otherwise the same as [ExperimentServiceAsync.fetch]. + */ + @MustBeClosed + fun fetch( + params: ExperimentFetchParams + ): CompletableFuture> = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/fetch`, but is + * otherwise the same as [ExperimentServiceAsync.fetchPost]. + */ + @MustBeClosed + fun fetchPost( + params: ExperimentFetchPostParams + ): CompletableFuture> = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/insert`, but is + * otherwise the same as [ExperimentServiceAsync.insert]. + */ + @MustBeClosed + fun insert( + params: ExperimentInsertParams + ): CompletableFuture> = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}/summarize`, but is + * otherwise the same as [ExperimentServiceAsync.summarize]. + */ + @MustBeClosed + fun summarize( + params: ExperimentSummarizeParams + ): CompletableFuture> = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ + @MustBeClosed + fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncImpl.kt index 0517c864..432baacd 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Experiment import com.braintrustdata.api.models.ExperimentCreateParams @@ -24,331 +31,397 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchExperimentEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeExperimentResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ExperimentServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ExperimentServiceAsync { +class ExperimentServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ExperimentServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ExperimentServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ExperimentServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new experiment. If there is an existing experiment in the project with the same name - * as the one specified in the request, will return the existing experiment unmodified - */ override fun create( params: ExperimentCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/experiment + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/experiment/{experiment_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/experiment/{experiment_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ExperimentListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/experiment + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/experiment/{experiment_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/experiment/{experiment_id}/feedback + withRawResponse().feedback(params, requestOptions).thenApply { it.parse() } + + override fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/experiment/{experiment_id}/fetch + withRawResponse().fetch(params, requestOptions).thenApply { it.parse() } + + override fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/experiment/{experiment_id}/fetch + withRawResponse().fetchPost(params, requestOptions).thenApply { it.parse() } + + override fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/experiment/{experiment_id}/insert + withRawResponse().insert(params, requestOptions).thenApply { it.parse() } + + override fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/experiment/{experiment_id}/summarize + withRawResponse().summarize(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ExperimentServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ExperimentCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an experiment object by its id */ - override fun retrieve( - params: ExperimentRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an experiment object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: ExperimentUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all experiments. The experiments are sorted by creation date, with the most - * recently-created experiments coming first - */ - override fun list( - params: ExperimentListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ExperimentListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ExperimentListPageAsync.of( + ExperimentServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { ExperimentListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an experiment object by its id */ - override fun delete( - params: ExperimentDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Log feedback for a set of experiment events */ - override fun feedback( - params: ExperimentFeedbackParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in an experiment. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body - */ - override fun fetch( - params: ExperimentFetchParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in an experiment. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: ExperimentFetchPostParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the experiment */ - override fun insert( - params: ExperimentInsertParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val summarizeHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val summarizeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Summarize experiment */ - override fun summarize( - params: ExperimentSummarizeParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0), "summarize") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { summarizeHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0), "summarize") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { summarizeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsync.kt index 59c3bcaf..b625969e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Function import com.braintrustdata.api.models.FunctionCreateParams import com.braintrustdata.api.models.FunctionDeleteParams @@ -15,25 +14,38 @@ import com.braintrustdata.api.models.FunctionListParams import com.braintrustdata.api.models.FunctionReplaceParams import com.braintrustdata.api.models.FunctionRetrieveParams import com.braintrustdata.api.models.FunctionUpdateParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.Optional import java.util.concurrent.CompletableFuture interface FunctionServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new function. If there is an existing function in the project with the same slug as * the one specified in the request, will return the existing function unmodified */ - @JvmOverloads + fun create(params: FunctionCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: FunctionCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a function object by its id */ - @JvmOverloads + fun retrieve(params: FunctionRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: FunctionRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -41,44 +53,194 @@ interface FunctionServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: FunctionUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: FunctionUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all functions. The functions are sorted by creation date, with the most * recently-created functions coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(FunctionListParams.none()) + + /** @see [list] */ fun list( - params: FunctionListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: FunctionListParams = FunctionListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: FunctionListParams = FunctionListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(FunctionListParams.none(), requestOptions) + /** Delete a function object by its id */ - @JvmOverloads + fun delete(params: FunctionDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: FunctionDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Invoke a function. */ - @JvmOverloads + fun invoke(params: FunctionInvokeParams): CompletableFuture> = + invoke(params, RequestOptions.none()) + + /** @see [invoke] */ fun invoke( params: FunctionInvokeParams, - requestOptions: RequestOptions = RequestOptions.none() - ): CompletableFuture + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> /** * Create or replace function. If there is an existing function in the project with the same * slug as the one specified in the request, will replace the existing function with the * provided fields */ - @JvmOverloads + fun replace(params: FunctionReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: FunctionReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [FunctionServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/function`, but is otherwise the same as + * [FunctionServiceAsync.create]. + */ + @MustBeClosed + fun create(params: FunctionCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: FunctionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/function/{function_id}`, but is otherwise the + * same as [FunctionServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: FunctionRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: FunctionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/function/{function_id}`, but is otherwise the + * same as [FunctionServiceAsync.update]. + */ + @MustBeClosed + fun update(params: FunctionUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: FunctionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/function`, but is otherwise the same as + * [FunctionServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(FunctionListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: FunctionListParams = FunctionListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: FunctionListParams = FunctionListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(FunctionListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/function/{function_id}`, but is otherwise the + * same as [FunctionServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: FunctionDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: FunctionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/function/{function_id}/invoke`, but is + * otherwise the same as [FunctionServiceAsync.invoke]. + */ + @MustBeClosed + fun invoke( + params: FunctionInvokeParams + ): CompletableFuture>> = + invoke(params, RequestOptions.none()) + + /** @see [invoke] */ + @MustBeClosed + fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture>> + + /** + * Returns a raw HTTP response for `put /v1/function`, but is otherwise the same as + * [FunctionServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: FunctionReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: FunctionReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncImpl.kt index 006ad090..27377950 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Function import com.braintrustdata.api.models.FunctionCreateParams @@ -18,232 +25,285 @@ import com.braintrustdata.api.models.FunctionListParams import com.braintrustdata.api.models.FunctionReplaceParams import com.braintrustdata.api.models.FunctionRetrieveParams import com.braintrustdata.api.models.FunctionUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler +import java.util.Optional import java.util.concurrent.CompletableFuture -class FunctionServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : FunctionServiceAsync { +class FunctionServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + FunctionServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: FunctionServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): FunctionServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new function. If there is an existing function in the project with the same slug as - * the one specified in the request, will return the existing function unmodified - */ override fun create( params: FunctionCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/function + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: FunctionRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/function/{function_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: FunctionUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/function/{function_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: FunctionListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/function + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: FunctionDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/function/{function_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions, + ): CompletableFuture> = + // post /v1/function/{function_id}/invoke + withRawResponse().invoke(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: FunctionReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/function + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + FunctionServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: FunctionCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "function") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a function object by its id */ - override fun retrieve( - params: FunctionRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: FunctionRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "function", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a function object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: FunctionUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: FunctionUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "function", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all functions. The functions are sorted by creation date, with the most - * recently-created functions coming first - */ - override fun list( - params: FunctionListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: FunctionListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "function") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + FunctionListPageAsync.of( + FunctionServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { FunctionListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a function object by its id */ - override fun delete( - params: FunctionDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: FunctionDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "function", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val invokeHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val invokeHandler: Handler> = + jsonHandler>(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Invoke a function. */ - override fun invoke( - params: FunctionInvokeParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "function", params.getPathParam(0), "invoke") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response.use { invokeHandler.handle(it) } + override fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions, + ): CompletableFuture>> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "function", params.getPathParam(0), "invoke") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { invokeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.ifPresent { it.validate() } + } + } + } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace function. If there is an existing function in the project with the same - * slug as the one specified in the request, will replace the existing function with the - * provided fields - */ - override fun replace( - params: FunctionReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: FunctionReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "function") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsync.kt index 62c6f177..9c172789 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Group import com.braintrustdata.api.models.GroupCreateParams import com.braintrustdata.api.models.GroupDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.GroupListParams import com.braintrustdata.api.models.GroupReplaceParams import com.braintrustdata.api.models.GroupRetrieveParams import com.braintrustdata.api.models.GroupUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface GroupServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new group. If there is an existing group with the same name as the one specified in * the request, will return the existing group unmodified */ - @JvmOverloads + fun create(params: GroupCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: GroupCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a group object by its id */ - @JvmOverloads + fun retrieve(params: GroupRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: GroupRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,36 +50,164 @@ interface GroupServiceAsync { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: GroupUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: GroupUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all groups. The groups are sorted by creation date, with the most recently-created * groups coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(GroupListParams.none()) + + /** @see [list] */ fun list( - params: GroupListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: GroupListParams = GroupListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: GroupListParams = GroupListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(GroupListParams.none(), requestOptions) + /** Delete a group object by its id */ - @JvmOverloads + fun delete(params: GroupDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: GroupDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace group. If there is an existing group with the same name as the one * specified in the request, will replace the existing group with the provided fields */ - @JvmOverloads + fun replace(params: GroupReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: GroupReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [GroupServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/group`, but is otherwise the same as + * [GroupServiceAsync.create]. + */ + @MustBeClosed + fun create(params: GroupCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: GroupCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/group/{group_id}`, but is otherwise the same as + * [GroupServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: GroupRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: GroupRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/group/{group_id}`, but is otherwise the same + * as [GroupServiceAsync.update]. + */ + @MustBeClosed + fun update(params: GroupUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: GroupUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/group`, but is otherwise the same as + * [GroupServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(GroupListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: GroupListParams = GroupListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: GroupListParams = GroupListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(GroupListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/group/{group_id}`, but is otherwise the same + * as [GroupServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: GroupDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: GroupDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/group`, but is otherwise the same as + * [GroupServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: GroupReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: GroupReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncImpl.kt index aebfd0ae..db541802 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Group import com.braintrustdata.api.models.GroupCreateParams @@ -16,207 +23,246 @@ import com.braintrustdata.api.models.GroupListParams import com.braintrustdata.api.models.GroupReplaceParams import com.braintrustdata.api.models.GroupRetrieveParams import com.braintrustdata.api.models.GroupUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class GroupServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : GroupServiceAsync { +class GroupServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + GroupServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: GroupServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): GroupServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new group. If there is an existing group with the same name as the one specified in - * the request, will return the existing group unmodified - */ override fun create( params: GroupCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/group + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: GroupRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/group/{group_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: GroupUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/group/{group_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: GroupListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/group + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: GroupDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/group/{group_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: GroupReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/group + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GroupServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: GroupCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "group") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a group object by its id */ - override fun retrieve( - params: GroupRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: GroupRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "group", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a group object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update( - params: GroupUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: GroupUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "group", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all groups. The groups are sorted by creation date, with the most recently-created - * groups coming first - */ - override fun list( - params: GroupListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: GroupListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "group") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + GroupListPageAsync.of( + GroupServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { GroupListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a group object by its id */ - override fun delete( - params: GroupDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: GroupDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "group", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace group. If there is an existing group with the same name as the one - * specified in the request, will replace the existing group with the provided fields - */ - override fun replace( - params: GroupReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: GroupReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "group") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsync.kt index f1cd38e1..a224dbd9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Organization import com.braintrustdata.api.models.OrganizationDeleteParams import com.braintrustdata.api.models.OrganizationListPageAsync @@ -12,17 +11,26 @@ import com.braintrustdata.api.models.OrganizationListParams import com.braintrustdata.api.models.OrganizationRetrieveParams import com.braintrustdata.api.models.OrganizationUpdateParams import com.braintrustdata.api.services.async.organizations.MemberServiceAsync +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface OrganizationServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun members(): MemberServiceAsync /** Get an organization object by its id */ - @JvmOverloads + fun retrieve(params: OrganizationRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: OrganizationRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -30,26 +38,130 @@ interface OrganizationServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: OrganizationUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: OrganizationUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all organizations. The organizations are sorted by creation date, with the most * recently-created organizations coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(OrganizationListParams.none()) + + /** @see [list] */ fun list( - params: OrganizationListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: OrganizationListParams = OrganizationListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: OrganizationListParams = OrganizationListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(OrganizationListParams.none(), requestOptions) + /** Delete an organization object by its id */ - @JvmOverloads + fun delete(params: OrganizationDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: OrganizationDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [OrganizationServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + fun members(): MemberServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `get /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve( + params: OrganizationRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: OrganizationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationServiceAsync.update]. + */ + @MustBeClosed + fun update( + params: OrganizationUpdateParams + ): CompletableFuture> = update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/organization`, but is otherwise the same as + * [OrganizationServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(OrganizationListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: OrganizationListParams = OrganizationListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: OrganizationListParams = OrganizationListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(OrganizationListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationServiceAsync.delete]. + */ + @MustBeClosed + fun delete( + params: OrganizationDeleteParams + ): CompletableFuture> = delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncImpl.kt index 2ff92c1d..08667293 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Organization import com.braintrustdata.api.models.OrganizationDeleteParams @@ -16,145 +23,182 @@ import com.braintrustdata.api.models.OrganizationRetrieveParams import com.braintrustdata.api.models.OrganizationUpdateParams import com.braintrustdata.api.services.async.organizations.MemberServiceAsync import com.braintrustdata.api.services.async.organizations.MemberServiceAsyncImpl -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class OrganizationServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : OrganizationServiceAsync { +class OrganizationServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + OrganizationServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: OrganizationServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } private val members: MemberServiceAsync by lazy { MemberServiceAsyncImpl(clientOptions) } - override fun members(): MemberServiceAsync = members + override fun withRawResponse(): OrganizationServiceAsync.WithRawResponse = withRawResponse - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun members(): MemberServiceAsync = members - /** Get an organization object by its id */ override fun retrieve( params: OrganizationRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/organization/{organization_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/organization/{organization_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: OrganizationListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/organization + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/organization/{organization_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + OrganizationServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val members: MemberServiceAsync.WithRawResponse by lazy { + MemberServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun members(): MemberServiceAsync.WithRawResponse = members + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: OrganizationRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an organization object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: OrganizationUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all organizations. The organizations are sorted by creation date, with the most - * recently-created organizations coming first - */ - override fun list( - params: OrganizationListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "organization") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: OrganizationListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "organization") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + OrganizationListPageAsync.of( + OrganizationServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { OrganizationListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an organization object by its id */ - override fun delete( - params: OrganizationDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsync.kt index a5c58d32..beca7a59 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ProjectScore import com.braintrustdata.api.models.ProjectScoreCreateParams import com.braintrustdata.api.models.ProjectScoreDeleteParams @@ -13,26 +12,38 @@ import com.braintrustdata.api.models.ProjectScoreListParams import com.braintrustdata.api.models.ProjectScoreReplaceParams import com.braintrustdata.api.models.ProjectScoreRetrieveParams import com.braintrustdata.api.models.ProjectScoreUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ProjectScoreServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new project_score. If there is an existing project_score in the project with the * same name as the one specified in the request, will return the existing project_score * unmodified */ - @JvmOverloads + fun create(params: ProjectScoreCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectScoreCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a project_score object by its id */ - @JvmOverloads + fun retrieve(params: ProjectScoreRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectScoreRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -40,27 +51,44 @@ interface ProjectScoreServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectScoreUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectScoreUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all project_scores. The project_scores are sorted by creation date, with the most * recently-created project_scores coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(ProjectScoreListParams.none()) + + /** @see [list] */ fun list( - params: ProjectScoreListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectScoreListParams = ProjectScoreListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: ProjectScoreListParams = ProjectScoreListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(ProjectScoreListParams.none(), requestOptions) + /** Delete a project_score object by its id */ - @JvmOverloads + fun delete(params: ProjectScoreDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectScoreDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -68,9 +96,129 @@ interface ProjectScoreServiceAsync { * the same name as the one specified in the request, will replace the existing project_score * with the provided fields */ - @JvmOverloads + fun replace(params: ProjectScoreReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ProjectScoreReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [ProjectScoreServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_score`, but is otherwise the same as + * [ProjectScoreServiceAsync.create]. + */ + @MustBeClosed + fun create( + params: ProjectScoreCreateParams + ): CompletableFuture> = create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectScoreCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve( + params: ProjectScoreRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectScoreRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreServiceAsync.update]. + */ + @MustBeClosed + fun update( + params: ProjectScoreUpdateParams + ): CompletableFuture> = update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectScoreUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project_score`, but is otherwise the same as + * [ProjectScoreServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(ProjectScoreListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectScoreListParams = ProjectScoreListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectScoreListParams = ProjectScoreListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(ProjectScoreListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreServiceAsync.delete]. + */ + @MustBeClosed + fun delete( + params: ProjectScoreDeleteParams + ): CompletableFuture> = delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/project_score`, but is otherwise the same as + * [ProjectScoreServiceAsync.replace]. + */ + @MustBeClosed + fun replace( + params: ProjectScoreReplaceParams + ): CompletableFuture> = replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncImpl.kt index 8953beb8..cde96d23 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ProjectScore import com.braintrustdata.api.models.ProjectScoreCreateParams @@ -16,209 +23,246 @@ import com.braintrustdata.api.models.ProjectScoreListParams import com.braintrustdata.api.models.ProjectScoreReplaceParams import com.braintrustdata.api.models.ProjectScoreRetrieveParams import com.braintrustdata.api.models.ProjectScoreUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ProjectScoreServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectScoreServiceAsync { +class ProjectScoreServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectScoreServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ProjectScoreServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ProjectScoreServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new project_score. If there is an existing project_score in the project with the - * same name as the one specified in the request, will return the existing project_score - * unmodified - */ override fun create( params: ProjectScoreCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project_score + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: ProjectScoreRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project_score/{project_score_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: ProjectScoreUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/project_score/{project_score_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ProjectScoreListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project_score + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/project_score/{project_score_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/project_score + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectScoreServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectScoreCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_score") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a project_score object by its id */ - override fun retrieve( - params: ProjectScoreRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ProjectScoreRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a project_score object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: ProjectScoreUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: ProjectScoreUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all project_scores. The project_scores are sorted by creation date, with the most - * recently-created project_scores coming first - */ - override fun list( - params: ProjectScoreListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ProjectScoreListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_score") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ProjectScoreListPageAsync.of( + ProjectScoreServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { ProjectScoreListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a project_score object by its id */ - override fun delete( - params: ProjectScoreDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace project_score. If there is an existing project_score in the project with - * the same name as the one specified in the request, will replace the existing project_score - * with the provided fields - */ - override fun replace( - params: ProjectScoreReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "project_score") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsync.kt index a9b81dd5..c1c67326 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Project import com.braintrustdata.api.models.ProjectCreateParams import com.braintrustdata.api.models.ProjectDeleteParams @@ -13,27 +12,39 @@ import com.braintrustdata.api.models.ProjectListParams import com.braintrustdata.api.models.ProjectRetrieveParams import com.braintrustdata.api.models.ProjectUpdateParams import com.braintrustdata.api.services.async.projects.LogServiceAsync +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ProjectServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun logs(): LogServiceAsync /** * Create a new project. If there is an existing project with the same name as the one specified * in the request, will return the existing project unmodified */ - @JvmOverloads + fun create(params: ProjectCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a project object by its id */ - @JvmOverloads + fun retrieve(params: ProjectRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -41,26 +52,140 @@ interface ProjectServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all projects. The projects are sorted by creation date, with the most * recently-created projects coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(ProjectListParams.none()) + + /** @see [list] */ fun list( - params: ProjectListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectListParams = ProjectListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: ProjectListParams = ProjectListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(ProjectListParams.none(), requestOptions) + /** Delete a project object by its id */ - @JvmOverloads + fun delete(params: ProjectDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [ProjectServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + fun logs(): LogServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/project`, but is otherwise the same as + * [ProjectServiceAsync.create]. + */ + @MustBeClosed + fun create(params: ProjectCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project/{project_id}`, but is otherwise the same + * as [ProjectServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ProjectRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/project/{project_id}`, but is otherwise the + * same as [ProjectServiceAsync.update]. + */ + @MustBeClosed + fun update(params: ProjectUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project`, but is otherwise the same as + * [ProjectServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(ProjectListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectListParams = ProjectListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectListParams = ProjectListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(ProjectListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project/{project_id}`, but is otherwise the + * same as [ProjectServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: ProjectDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncImpl.kt index 02e1fd79..dba161a5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Project import com.braintrustdata.api.models.ProjectCreateParams @@ -17,178 +24,219 @@ import com.braintrustdata.api.models.ProjectRetrieveParams import com.braintrustdata.api.models.ProjectUpdateParams import com.braintrustdata.api.services.async.projects.LogServiceAsync import com.braintrustdata.api.services.async.projects.LogServiceAsyncImpl -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ProjectServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectServiceAsync { +class ProjectServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ProjectServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } private val logs: LogServiceAsync by lazy { LogServiceAsyncImpl(clientOptions) } - override fun logs(): LogServiceAsync = logs + override fun withRawResponse(): ProjectServiceAsync.WithRawResponse = withRawResponse - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun logs(): LogServiceAsync = logs - /** - * Create a new project. If there is an existing project with the same name as the one specified - * in the request, will return the existing project unmodified - */ override fun create( params: ProjectCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project + withRawResponse().create(params, requestOptions).thenApply { it.parse() } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a project object by its id */ override fun retrieve( params: ProjectRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project/{project_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a project object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ override fun update( params: ProjectUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/project/{project_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ProjectListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ProjectDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/project/{project_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val logs: LogServiceAsync.WithRawResponse by lazy { + LogServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun logs(): LogServiceAsync.WithRawResponse = logs + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ProjectRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } - /** - * List out all projects. The projects are sorted by creation date, with the most - * recently-created projects coming first - */ - override fun list( - params: ProjectListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: ProjectUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } - .let { ProjectListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ProjectListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ProjectListPageAsync.of( + ProjectServiceAsyncImpl(clientOptions), + params, + it, + ) + } + } + } + } - /** Delete a project object by its id */ - override fun delete( - params: ProjectDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ProjectDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsync.kt index 7c06cd95..6d681309 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ProjectTag import com.braintrustdata.api.models.ProjectTagCreateParams import com.braintrustdata.api.models.ProjectTagDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.ProjectTagListParams import com.braintrustdata.api.models.ProjectTagReplaceParams import com.braintrustdata.api.models.ProjectTagRetrieveParams import com.braintrustdata.api.models.ProjectTagUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ProjectTagServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new project_tag. If there is an existing project_tag in the project with the same * name as the one specified in the request, will return the existing project_tag unmodified */ - @JvmOverloads + fun create(params: ProjectTagCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectTagCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a project_tag object by its id */ - @JvmOverloads + fun retrieve(params: ProjectTagRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectTagRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,27 +50,44 @@ interface ProjectTagServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectTagUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectTagUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all project_tags. The project_tags are sorted by creation date, with the most * recently-created project_tags coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(ProjectTagListParams.none()) + + /** @see [list] */ fun list( - params: ProjectTagListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectTagListParams = ProjectTagListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: ProjectTagListParams = ProjectTagListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(ProjectTagListParams.none(), requestOptions) + /** Delete a project_tag object by its id */ - @JvmOverloads + fun delete(params: ProjectTagDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectTagDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -67,9 +95,125 @@ interface ProjectTagServiceAsync { * same name as the one specified in the request, will replace the existing project_tag with the * provided fields */ - @JvmOverloads + fun replace(params: ProjectTagReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ProjectTagReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [ProjectTagServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_tag`, but is otherwise the same as + * [ProjectTagServiceAsync.create]. + */ + @MustBeClosed + fun create(params: ProjectTagCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectTagCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project_tag/{project_tag_id}`, but is otherwise + * the same as [ProjectTagServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve( + params: ProjectTagRetrieveParams + ): CompletableFuture> = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectTagRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/project_tag/{project_tag_id}`, but is + * otherwise the same as [ProjectTagServiceAsync.update]. + */ + @MustBeClosed + fun update(params: ProjectTagUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectTagUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project_tag`, but is otherwise the same as + * [ProjectTagServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(ProjectTagListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectTagListParams = ProjectTagListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectTagListParams = ProjectTagListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(ProjectTagListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project_tag/{project_tag_id}`, but is + * otherwise the same as [ProjectTagServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: ProjectTagDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/project_tag`, but is otherwise the same as + * [ProjectTagServiceAsync.replace]. + */ + @MustBeClosed + fun replace( + params: ProjectTagReplaceParams + ): CompletableFuture> = replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncImpl.kt index 66372dea..d12a821a 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ProjectTag import com.braintrustdata.api.models.ProjectTagCreateParams @@ -16,208 +23,246 @@ import com.braintrustdata.api.models.ProjectTagListParams import com.braintrustdata.api.models.ProjectTagReplaceParams import com.braintrustdata.api.models.ProjectTagRetrieveParams import com.braintrustdata.api.models.ProjectTagUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ProjectTagServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectTagServiceAsync { +class ProjectTagServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectTagServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ProjectTagServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ProjectTagServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new project_tag. If there is an existing project_tag in the project with the same - * name as the one specified in the request, will return the existing project_tag unmodified - */ override fun create( params: ProjectTagCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project_tag + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: ProjectTagRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project_tag/{project_tag_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: ProjectTagUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/project_tag/{project_tag_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ProjectTagListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project_tag + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/project_tag/{project_tag_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/project_tag + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectTagServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectTagCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_tag") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a project_tag object by its id */ - override fun retrieve( - params: ProjectTagRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ProjectTagRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a project_tag object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: ProjectTagUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: ProjectTagUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all project_tags. The project_tags are sorted by creation date, with the most - * recently-created project_tags coming first - */ - override fun list( - params: ProjectTagListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ProjectTagListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_tag") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ProjectTagListPageAsync.of( + ProjectTagServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { ProjectTagListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a project_tag object by its id */ - override fun delete( - params: ProjectTagDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace project_tag. If there is an existing project_tag in the project with the - * same name as the one specified in the request, will replace the existing project_tag with the - * provided fields - */ - override fun replace( - params: ProjectTagReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "project_tag") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsync.kt index 2d444758..afb7a900 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Prompt import com.braintrustdata.api.models.PromptCreateParams import com.braintrustdata.api.models.PromptDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.PromptListParams import com.braintrustdata.api.models.PromptReplaceParams import com.braintrustdata.api.models.PromptRetrieveParams import com.braintrustdata.api.models.PromptUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface PromptServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new prompt. If there is an existing prompt in the project with the same slug as the * one specified in the request, will return the existing prompt unmodified */ - @JvmOverloads + fun create(params: PromptCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: PromptCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a prompt object by its id */ - @JvmOverloads + fun retrieve(params: PromptRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: PromptRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,36 +50,166 @@ interface PromptServiceAsync { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: PromptUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: PromptUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all prompts. The prompts are sorted by creation date, with the most recently-created * prompts coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(PromptListParams.none()) + + /** @see [list] */ fun list( - params: PromptListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: PromptListParams = PromptListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list( + params: PromptListParams = PromptListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(PromptListParams.none(), requestOptions) + /** Delete a prompt object by its id */ - @JvmOverloads + fun delete(params: PromptDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: PromptDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace prompt. If there is an existing prompt in the project with the same slug as * the one specified in the request, will replace the existing prompt with the provided fields */ - @JvmOverloads + fun replace(params: PromptReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: PromptReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** + * A view of [PromptServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/prompt`, but is otherwise the same as + * [PromptServiceAsync.create]. + */ + @MustBeClosed + fun create(params: PromptCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: PromptCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/prompt/{prompt_id}`, but is otherwise the same + * as [PromptServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: PromptRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: PromptRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/prompt/{prompt_id}`, but is otherwise the same + * as [PromptServiceAsync.update]. + */ + @MustBeClosed + fun update(params: PromptUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: PromptUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/prompt`, but is otherwise the same as + * [PromptServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(PromptListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: PromptListParams = PromptListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: PromptListParams = PromptListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(PromptListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/prompt/{prompt_id}`, but is otherwise the + * same as [PromptServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: PromptDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: PromptDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/prompt`, but is otherwise the same as + * [PromptServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: PromptReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: PromptReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncImpl.kt index f892b1fd..7772aa68 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Prompt import com.braintrustdata.api.models.PromptCreateParams @@ -16,207 +23,246 @@ import com.braintrustdata.api.models.PromptListParams import com.braintrustdata.api.models.PromptReplaceParams import com.braintrustdata.api.models.PromptRetrieveParams import com.braintrustdata.api.models.PromptUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class PromptServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : PromptServiceAsync { +class PromptServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + PromptServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: PromptServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): PromptServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new prompt. If there is an existing prompt in the project with the same slug as the - * one specified in the request, will return the existing prompt unmodified - */ override fun create( params: PromptCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/prompt + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: PromptRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/prompt/{prompt_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: PromptUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/prompt/{prompt_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: PromptListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/prompt + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: PromptDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/prompt/{prompt_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: PromptReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/prompt + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + PromptServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: PromptCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "prompt") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a prompt object by its id */ - override fun retrieve( - params: PromptRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: PromptRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a prompt object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: PromptUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: PromptUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all prompts. The prompts are sorted by creation date, with the most recently-created - * prompts coming first - */ - override fun list( - params: PromptListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: PromptListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "prompt") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + PromptListPageAsync.of( + PromptServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { PromptListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a prompt object by its id */ - override fun delete( - params: PromptDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: PromptDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace prompt. If there is an existing prompt in the project with the same slug as - * the one specified in the request, will replace the existing prompt with the provided fields - */ - override fun replace( - params: PromptReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: PromptReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "prompt") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsync.kt index e5b84aba..988acc47 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Role import com.braintrustdata.api.models.RoleCreateParams import com.braintrustdata.api.models.RoleDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.RoleListParams import com.braintrustdata.api.models.RoleReplaceParams import com.braintrustdata.api.models.RoleRetrieveParams import com.braintrustdata.api.models.RoleUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface RoleServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new role. If there is an existing role with the same name as the one specified in * the request, will return the existing role unmodified */ - @JvmOverloads + fun create(params: RoleCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: RoleCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a role object by its id */ - @JvmOverloads + fun retrieve(params: RoleRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: RoleRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,36 +50,163 @@ interface RoleServiceAsync { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: RoleUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: RoleUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all roles. The roles are sorted by creation date, with the most recently-created * roles coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(RoleListParams.none()) + + /** @see [list] */ fun list( - params: RoleListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: RoleListParams = RoleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see [list] */ + fun list(params: RoleListParams = RoleListParams.none()): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(RoleListParams.none(), requestOptions) + /** Delete a role object by its id */ - @JvmOverloads + fun delete(params: RoleDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: RoleDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace role. If there is an existing role with the same name as the one specified * in the request, will replace the existing role with the provided fields */ - @JvmOverloads + fun replace(params: RoleReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: RoleReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [RoleServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/role`, but is otherwise the same as + * [RoleServiceAsync.create]. + */ + @MustBeClosed + fun create(params: RoleCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: RoleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/role/{role_id}`, but is otherwise the same as + * [RoleServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: RoleRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: RoleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/role/{role_id}`, but is otherwise the same as + * [RoleServiceAsync.update]. + */ + @MustBeClosed + fun update(params: RoleUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: RoleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/role`, but is otherwise the same as + * [RoleServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(RoleListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: RoleListParams = RoleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: RoleListParams = RoleListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(RoleListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/role/{role_id}`, but is otherwise the same as + * [RoleServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: RoleDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: RoleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/role`, but is otherwise the same as + * [RoleServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: RoleReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: RoleReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncImpl.kt index 87b3e814..f4809686 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Role import com.braintrustdata.api.models.RoleCreateParams @@ -16,207 +23,246 @@ import com.braintrustdata.api.models.RoleListParams import com.braintrustdata.api.models.RoleReplaceParams import com.braintrustdata.api.models.RoleRetrieveParams import com.braintrustdata.api.models.RoleUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class RoleServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : RoleServiceAsync { +class RoleServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + RoleServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: RoleServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): RoleServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new role. If there is an existing role with the same name as the one specified in - * the request, will return the existing role unmodified - */ override fun create( params: RoleCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/role + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: RoleRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/role/{role_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: RoleUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/role/{role_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: RoleListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/role + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: RoleDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/role/{role_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: RoleReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/role + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + RoleServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: RoleCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "role") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a role object by its id */ - override fun retrieve( - params: RoleRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: RoleRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "role", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a role object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update( - params: RoleUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: RoleUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "role", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all roles. The roles are sorted by creation date, with the most recently-created - * roles coming first - */ - override fun list( - params: RoleListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: RoleListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "role") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + RoleListPageAsync.of( + RoleServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { RoleListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a role object by its id */ - override fun delete( - params: RoleDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: RoleDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "role", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace role. If there is an existing role with the same name as the one specified - * in the request, will replace the existing role with the provided fields - */ - override fun replace( - params: RoleReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: RoleReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "role") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsync.kt new file mode 100644 index 00000000..442357ea --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsync.kt @@ -0,0 +1,218 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.models.SpanIFrame +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeListPageAsync +import com.braintrustdata.api.models.SpanIframeListParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.concurrent.CompletableFuture + +interface SpanIframeServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Create a new span_iframe. If there is an existing span_iframe with the same name as the one + * specified in the request, will return the existing span_iframe unmodified + */ + fun create(params: SpanIframeCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ + fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Get a span_iframe object by its id */ + fun retrieve(params: SpanIframeRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Partially update a span_iframe object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ + fun update(params: SpanIframeUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ + fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * List out all span_iframes. The span_iframes are sorted by creation date, with the most + * recently-created span_iframes coming first + */ + fun list(): CompletableFuture = list(SpanIframeListParams.none()) + + /** @see [list] */ + fun list( + params: SpanIframeListParams = SpanIframeListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see [list] */ + fun list( + params: SpanIframeListParams = SpanIframeListParams.none() + ): CompletableFuture = list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(SpanIframeListParams.none(), requestOptions) + + /** Delete a span_iframe object by its id */ + fun delete(params: SpanIframeDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Create or replace span_iframe. If there is an existing span_iframe with the same name as the + * one specified in the request, will replace the existing span_iframe with the provided fields + */ + fun replace(params: SpanIframeReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [SpanIframeServiceAsync] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/span_iframe`, but is otherwise the same as + * [SpanIframeServiceAsync.create]. + */ + @MustBeClosed + fun create(params: SpanIframeCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/span_iframe/{span_iframe_id}`, but is otherwise + * the same as [SpanIframeServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve( + params: SpanIframeRetrieveParams + ): CompletableFuture> = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/span_iframe/{span_iframe_id}`, but is + * otherwise the same as [SpanIframeServiceAsync.update]. + */ + @MustBeClosed + fun update(params: SpanIframeUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/span_iframe`, but is otherwise the same as + * [SpanIframeServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(SpanIframeListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: SpanIframeListParams = SpanIframeListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: SpanIframeListParams = SpanIframeListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(SpanIframeListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/span_iframe/{span_iframe_id}`, but is + * otherwise the same as [SpanIframeServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: SpanIframeDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/span_iframe`, but is otherwise the same as + * [SpanIframeServiceAsync.replace]. + */ + @MustBeClosed + fun replace( + params: SpanIframeReplaceParams + ): CompletableFuture> = replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncImpl.kt new file mode 100644 index 00000000..6dd3a6b3 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncImpl.kt @@ -0,0 +1,270 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.core.ClientOptions +import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler +import com.braintrustdata.api.core.http.HttpMethod +import com.braintrustdata.api.core.http.HttpRequest +import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync +import com.braintrustdata.api.errors.BraintrustError +import com.braintrustdata.api.models.SpanIFrame +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeListPageAsync +import com.braintrustdata.api.models.SpanIframeListParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams +import java.util.concurrent.CompletableFuture + +class SpanIframeServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + SpanIframeServiceAsync { + + private val withRawResponse: SpanIframeServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): SpanIframeServiceAsync.WithRawResponse = withRawResponse + + override fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/span_iframe + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/span_iframe/{span_iframe_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/span_iframe/{span_iframe_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: SpanIframeListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/span_iframe + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/span_iframe/{span_iframe_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/span_iframe + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SpanIframeServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "span_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: SpanIframeListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "span_iframe") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + SpanIframeListPageAsync.of( + SpanIframeServiceAsyncImpl(clientOptions), + params, + it, + ) + } + } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "span_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsync.kt index 14126ddc..5411c270 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsync.kt @@ -1,19 +1,67 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.TopLevelHelloWorldParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface TopLevelServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Default endpoint. Simply replies with 'Hello, World!'. Authorization is not required */ - @JvmOverloads + fun helloWorld(): CompletableFuture = helloWorld(TopLevelHelloWorldParams.none()) + + /** @see [helloWorld] */ fun helloWorld( - params: TopLevelHelloWorldParams, - requestOptions: RequestOptions = RequestOptions.none() + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** @see [helloWorld] */ + fun helloWorld( + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none() + ): CompletableFuture = helloWorld(params, RequestOptions.none()) + + /** @see [helloWorld] */ + fun helloWorld(requestOptions: RequestOptions): CompletableFuture = + helloWorld(TopLevelHelloWorldParams.none(), requestOptions) + + /** + * A view of [TopLevelServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `get /v1`, but is otherwise the same as + * [TopLevelServiceAsync.helloWorld]. + */ + @MustBeClosed + fun helloWorld(): CompletableFuture> = + helloWorld(TopLevelHelloWorldParams.none()) + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld( + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld( + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none() + ): CompletableFuture> = helloWorld(params, RequestOptions.none()) + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld(requestOptions: RequestOptions): CompletableFuture> = + helloWorld(TopLevelHelloWorldParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncImpl.kt index 62a80406..efc7d4ce 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncImpl.kt @@ -4,42 +4,59 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.stringHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.TopLevelHelloWorldParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.stringHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class TopLevelServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : TopLevelServiceAsync { +class TopLevelServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + TopLevelServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: TopLevelServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val helloWorldHandler: Handler = stringHandler().withErrorHandler(errorHandler) + override fun withRawResponse(): TopLevelServiceAsync.WithRawResponse = withRawResponse - /** Default endpoint. Simply replies with 'Hello, World!'. Authorization is not required */ override fun helloWorld( params: TopLevelHelloWorldParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response.use { helloWorldHandler.handle(it) } + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1 + withRawResponse().helloWorld(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + TopLevelServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val helloWorldHandler: Handler = + stringHandler().withErrorHandler(errorHandler) + + override fun helloWorld( + params: TopLevelHelloWorldParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { response.use { helloWorldHandler.handle(it) } } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsync.kt index e7d83503..2bf974c5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsync.kt @@ -1,32 +1,98 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.User import com.braintrustdata.api.models.UserListPageAsync import com.braintrustdata.api.models.UserListParams import com.braintrustdata.api.models.UserRetrieveParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface UserServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Get a user object by its id */ - @JvmOverloads + fun retrieve(params: UserRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: UserRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all users. The users are sorted by creation date, with the most recently-created * users coming first */ - @JvmOverloads + fun list(): CompletableFuture = list(UserListParams.none()) + + /** @see [list] */ fun list( - params: UserListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: UserListParams = UserListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** @see [list] */ + fun list(params: UserListParams = UserListParams.none()): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): CompletableFuture = + list(UserListParams.none(), requestOptions) + + /** A view of [UserServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `get /v1/user/{user_id}`, but is otherwise the same as + * [UserServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: UserRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: UserRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/user`, but is otherwise the same as + * [UserServiceAsync.list]. + */ + @MustBeClosed + fun list(): CompletableFuture> = + list(UserListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: UserListParams = UserListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [list] */ + @MustBeClosed + fun list( + params: UserListParams = UserListParams.none() + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + requestOptions: RequestOptions + ): CompletableFuture> = + list(UserListParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncImpl.kt index 3cbcf8e1..54c73c41 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncImpl.kt @@ -4,86 +4,114 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.User import com.braintrustdata.api.models.UserListPageAsync import com.braintrustdata.api.models.UserListParams import com.braintrustdata.api.models.UserRetrieveParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class UserServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : UserServiceAsync { +class UserServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + UserServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: UserServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): UserServiceAsync.WithRawResponse = withRawResponse - /** Get a user object by its id */ override fun retrieve( params: UserRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "user", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/user/{user_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: UserListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/user + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + UserServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: UserRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "user", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all users. The users are sorted by creation date, with the most recently-created - * users coming first - */ - override fun list( - params: UserListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "user") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: UserListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "user") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + UserListPageAsync.of( + UserServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { UserListPageAsync.of(this, params, it) } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsync.kt index 805e10ff..f70248e9 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.View import com.braintrustdata.api.models.ViewCreateParams import com.braintrustdata.api.models.ViewDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.ViewListParams import com.braintrustdata.api.models.ViewReplaceParams import com.braintrustdata.api.models.ViewRetrieveParams import com.braintrustdata.api.models.ViewUpdateParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface ViewServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new view. If there is an existing view with the same name as the one specified in * the request, will return the existing view unmodified */ - @JvmOverloads + fun create(params: ViewCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ViewCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Get a view object by its id */ - @JvmOverloads + fun retrieve(params: ViewRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ViewRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @@ -39,36 +50,142 @@ interface ViewServiceAsync { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: ViewUpdateParams): CompletableFuture = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ViewUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * List out all views. The views are sorted by creation date, with the most recently-created * views coming first */ - @JvmOverloads + fun list(params: ViewListParams): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see [list] */ fun list( params: ViewListParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Delete a view object by its id */ - @JvmOverloads + fun delete(params: ViewDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ViewDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Create or replace view. If there is an existing view with the same name as the one specified * in the request, will replace the existing view with the provided fields */ - @JvmOverloads + fun replace(params: ViewReplaceParams): CompletableFuture = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ViewReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [ViewServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/view`, but is otherwise the same as + * [ViewServiceAsync.create]. + */ + @MustBeClosed + fun create(params: ViewCreateParams): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ViewCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/view/{view_id}`, but is otherwise the same as + * [ViewServiceAsync.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ViewRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ViewRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `patch /v1/view/{view_id}`, but is otherwise the same as + * [ViewServiceAsync.update]. + */ + @MustBeClosed + fun update(params: ViewUpdateParams): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ViewUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/view`, but is otherwise the same as + * [ViewServiceAsync.list]. + */ + @MustBeClosed + fun list(params: ViewListParams): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ViewListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `delete /v1/view/{view_id}`, but is otherwise the same as + * [ViewServiceAsync.delete]. + */ + @MustBeClosed + fun delete(params: ViewDeleteParams): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ViewDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put /v1/view`, but is otherwise the same as + * [ViewServiceAsync.replace]. + */ + @MustBeClosed + fun replace(params: ViewReplaceParams): CompletableFuture> = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ViewReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncImpl.kt index 9a9874ec..644bd149 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.View import com.braintrustdata.api.models.ViewCreateParams @@ -16,207 +23,246 @@ import com.braintrustdata.api.models.ViewListParams import com.braintrustdata.api.models.ViewReplaceParams import com.braintrustdata.api.models.ViewRetrieveParams import com.braintrustdata.api.models.ViewUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class ViewServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : ViewServiceAsync { +class ViewServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + ViewServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ViewServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ViewServiceAsync.WithRawResponse = withRawResponse - /** - * Create a new view. If there is an existing view with the same name as the one specified in - * the request, will return the existing view unmodified - */ override fun create( params: ViewCreateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/view + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: ViewRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/view/{view_id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: ViewUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/view/{view_id} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: ViewListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/view + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: ViewDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/view/{view_id} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + override fun replace( + params: ViewReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put /v1/view + withRawResponse().replace(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ViewServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ViewCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "view") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get a view object by its id */ - override fun retrieve( - params: ViewRetrieveParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ViewRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "view", params.getPathParam(0)) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update a view object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update( - params: ViewUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: ViewUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "view", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all views. The views are sorted by creation date, with the most recently-created - * views coming first - */ - override fun list( - params: ViewListParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ViewListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "view") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ViewListPageAsync.of( + ViewServiceAsyncImpl(clientOptions), + params, + it, + ) + } } } - .let { ViewListPageAsync.of(this, params, it) } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a view object by its id */ - override fun delete( - params: ViewDeleteParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ViewDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "view", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Create or replace view. If there is an existing view with the same name as the one specified - * in the request, will replace the existing view with the provided fields - */ - override fun replace( - params: ViewReplaceParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun replace( + params: ViewReplaceParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "view") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsync.kt index de4cc02c..78042415 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsync.kt @@ -1,20 +1,72 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async.organizations import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.OrganizationMemberUpdateParams import com.braintrustdata.api.models.PatchOrganizationMembersOutput +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface MemberServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Modify organization membership */ - @JvmOverloads + fun update(): CompletableFuture = + update(OrganizationMemberUpdateParams.none()) + + /** @see [update] */ fun update( - params: OrganizationMemberUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** @see [update] */ + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none() + ): CompletableFuture = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(requestOptions: RequestOptions): CompletableFuture = + update(OrganizationMemberUpdateParams.none(), requestOptions) + + /** + * A view of [MemberServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `patch /v1/organization/members`, but is otherwise the + * same as [MemberServiceAsync.update]. + */ + @MustBeClosed + fun update(): CompletableFuture> = + update(OrganizationMemberUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none() + ): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + requestOptions: RequestOptions + ): CompletableFuture> = + update(OrganizationMemberUpdateParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncImpl.kt index 73d5eaec..ac1cca4a 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncImpl.kt @@ -4,51 +4,69 @@ package com.braintrustdata.api.services.async.organizations import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.OrganizationMemberUpdateParams import com.braintrustdata.api.models.PatchOrganizationMembersOutput -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class MemberServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : MemberServiceAsync { +class MemberServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + MemberServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: MemberServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + override fun withRawResponse(): MemberServiceAsync.WithRawResponse = withRawResponse - /** Modify organization membership */ override fun update( params: OrganizationMemberUpdateParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "organization", "members") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // patch /v1/organization/members + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + MemberServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun update( + params: OrganizationMemberUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "organization", "members") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsync.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsync.kt index e799ba08..b1d19e58 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsync.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsync.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.async.projects import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchProjectLogsEventsResponse import com.braintrustdata.api.models.InsertEventsResponse @@ -12,41 +11,134 @@ import com.braintrustdata.api.models.ProjectLogFeedbackParams import com.braintrustdata.api.models.ProjectLogFetchParams import com.braintrustdata.api.models.ProjectLogFetchPostParams import com.braintrustdata.api.models.ProjectLogInsertParams +import com.google.errorprone.annotations.MustBeClosed import java.util.concurrent.CompletableFuture interface LogServiceAsync { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Log feedback for a set of project logs events */ - @JvmOverloads + fun feedback(params: ProjectLogFeedbackParams): CompletableFuture = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: ProjectLogFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in a project logs. Equivalent to the POST form of the same path, but with - * the parameters in the URL query rather than in the request body + * the parameters in the URL query rather than in the request body. For more complex queries, + * use the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: ProjectLogFetchParams): CompletableFuture = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: ProjectLogFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** * Fetch the events in a project logs. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost( + params: ProjectLogFetchPostParams + ): CompletableFuture = fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: ProjectLogFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** Insert a set of events into the project logs */ - @JvmOverloads + fun insert(params: ProjectLogInsertParams): CompletableFuture = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: ProjectLogInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + + /** A view of [LogServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/feedback`, but is + * otherwise the same as [LogServiceAsync.feedback]. + */ + @MustBeClosed + fun feedback( + params: ProjectLogFeedbackParams + ): CompletableFuture> = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: ProjectLogFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get /v1/project_logs/{project_id}/fetch`, but is + * otherwise the same as [LogServiceAsync.fetch]. + */ + @MustBeClosed + fun fetch( + params: ProjectLogFetchParams + ): CompletableFuture> = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/fetch`, but is + * otherwise the same as [LogServiceAsync.fetchPost]. + */ + @MustBeClosed + fun fetchPost( + params: ProjectLogFetchPostParams + ): CompletableFuture> = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/insert`, but is + * otherwise the same as [LogServiceAsync.insert]. + */ + @MustBeClosed + fun insert( + params: ProjectLogInsertParams + ): CompletableFuture> = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncImpl.kt index 23037f34..7c47266f 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.async.projects import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepareAsync import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchProjectLogsEventsResponse @@ -15,141 +22,169 @@ import com.braintrustdata.api.models.ProjectLogFeedbackParams import com.braintrustdata.api.models.ProjectLogFetchParams import com.braintrustdata.api.models.ProjectLogFetchPostParams import com.braintrustdata.api.models.ProjectLogInsertParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler import java.util.concurrent.CompletableFuture -class LogServiceAsyncImpl -constructor( - private val clientOptions: ClientOptions, -) : LogServiceAsync { +class LogServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + LogServiceAsync { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: LogServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): LogServiceAsync.WithRawResponse = withRawResponse - /** Log feedback for a set of project logs events */ override fun feedback( params: ProjectLogFeedbackParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project_logs/{project_id}/feedback + withRawResponse().feedback(params, requestOptions).thenApply { it.parse() } + + override fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/project_logs/{project_id}/fetch + withRawResponse().fetch(params, requestOptions).thenApply { it.parse() } + + override fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project_logs/{project_id}/fetch + withRawResponse().fetchPost(params, requestOptions).thenApply { it.parse() } + + override fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/project_logs/{project_id}/insert + withRawResponse().insert(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LogServiceAsync.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun feedback( + params: ProjectLogFeedbackParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a project logs. Equivalent to the POST form of the same path, but with - * the parameters in the URL query rather than in the request body - */ - override fun fetch( - params: ProjectLogFetchParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a project logs. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: ProjectLogFetchPostParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the project logs */ - override fun insert( - params: ProjectLogInsertParams, - requestOptions: RequestOptions - ): CompletableFuture { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.executeAsync(request, requestOptions).thenApply { response - -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclService.kt index b47af970..c94852cc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Acl import com.braintrustdata.api.models.AclBatchUpdateParams import com.braintrustdata.api.models.AclBatchUpdateResponse @@ -14,51 +13,184 @@ import com.braintrustdata.api.models.AclFindAndDeleteParams import com.braintrustdata.api.models.AclListPage import com.braintrustdata.api.models.AclListParams import com.braintrustdata.api.models.AclRetrieveParams +import com.google.errorprone.annotations.MustBeClosed interface AclService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new acl. If there is an existing acl with the same contents as the one specified in * the request, will return the existing acl unmodified */ - @JvmOverloads + fun create(params: AclCreateParams): Acl = create(params, RequestOptions.none()) + + /** @see [create] */ fun create(params: AclCreateParams, requestOptions: RequestOptions = RequestOptions.none()): Acl /** Get an acl object by its id */ - @JvmOverloads + fun retrieve(params: AclRetrieveParams): Acl = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: AclRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Acl /** * List out all acls. The acls are sorted by creation date, with the most recently-created acls * coming first */ - @JvmOverloads + fun list(params: AclListParams): AclListPage = list(params, RequestOptions.none()) + + /** @see [list] */ fun list( params: AclListParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AclListPage /** Delete an acl object by its id */ - @JvmOverloads + fun delete(params: AclDeleteParams): Acl = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete(params: AclDeleteParams, requestOptions: RequestOptions = RequestOptions.none()): Acl /** * Batch update acls. This operation is idempotent, so adding acls which already exist will have * no effect, and removing acls which do not exist will have no effect. */ - @JvmOverloads + fun batchUpdate(): AclBatchUpdateResponse = batchUpdate(AclBatchUpdateParams.none()) + + /** @see [batchUpdate] */ fun batchUpdate( - params: AclBatchUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + params: AclBatchUpdateParams = AclBatchUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): AclBatchUpdateResponse + /** @see [batchUpdate] */ + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none() + ): AclBatchUpdateResponse = batchUpdate(params, RequestOptions.none()) + + /** @see [batchUpdate] */ + fun batchUpdate(requestOptions: RequestOptions): AclBatchUpdateResponse = + batchUpdate(AclBatchUpdateParams.none(), requestOptions) + /** Delete a single acl */ - @JvmOverloads + fun findAndDelete(params: AclFindAndDeleteParams): Acl = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ fun findAndDelete( params: AclFindAndDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Acl + + /** A view of [AclService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/acl`, but is otherwise the same as + * [AclService.create]. + */ + @MustBeClosed + fun create(params: AclCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: AclCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/acl/{acl_id}`, but is otherwise the same as + * [AclService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: AclRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: AclRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/acl`, but is otherwise the same as + * [AclService.list]. + */ + @MustBeClosed + fun list(params: AclListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: AclListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `delete /v1/acl/{acl_id}`, but is otherwise the same as + * [AclService.delete]. + */ + @MustBeClosed + fun delete(params: AclDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: AclDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/acl/batch_update`, but is otherwise the same as + * [AclService.batchUpdate]. + */ + @MustBeClosed + fun batchUpdate(): HttpResponseFor = + batchUpdate(AclBatchUpdateParams.none()) + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate( + params: AclBatchUpdateParams = AclBatchUpdateParams.none() + ): HttpResponseFor = batchUpdate(params, RequestOptions.none()) + + /** @see [batchUpdate] */ + @MustBeClosed + fun batchUpdate(requestOptions: RequestOptions): HttpResponseFor = + batchUpdate(AclBatchUpdateParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/acl`, but is otherwise the same as + * [AclService.findAndDelete]. + */ + @MustBeClosed + fun findAndDelete(params: AclFindAndDeleteParams): HttpResponseFor = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ + @MustBeClosed + fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclServiceImpl.kt index a7b51e01..b6a1b9e0 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AclServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Acl import com.braintrustdata.api.models.AclBatchUpdateParams @@ -17,185 +24,211 @@ import com.braintrustdata.api.models.AclFindAndDeleteParams import com.braintrustdata.api.models.AclListPage import com.braintrustdata.api.models.AclListParams import com.braintrustdata.api.models.AclRetrieveParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class AclServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : AclService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new acl. If there is an existing acl with the same contents as the one specified in - * the request, will return the existing acl unmodified - */ - override fun create(params: AclCreateParams, requestOptions: RequestOptions): Acl { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } + +class AclServiceImpl internal constructor(private val clientOptions: ClientOptions) : AclService { + + private val withRawResponse: AclService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get an acl object by its id */ - override fun retrieve(params: AclRetrieveParams, requestOptions: RequestOptions): Acl { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "acl", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun withRawResponse(): AclService.WithRawResponse = withRawResponse + + override fun create(params: AclCreateParams, requestOptions: RequestOptions): Acl = + // post /v1/acl + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: AclRetrieveParams, requestOptions: RequestOptions): Acl = + // get /v1/acl/{acl_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun list(params: AclListParams, requestOptions: RequestOptions): AclListPage = + // get /v1/acl + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: AclDeleteParams, requestOptions: RequestOptions): Acl = + // delete /v1/acl/{acl_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun batchUpdate( + params: AclBatchUpdateParams, + requestOptions: RequestOptions, + ): AclBatchUpdateResponse = + // post /v1/acl/batch_update + withRawResponse().batchUpdate(params, requestOptions).parse() + + override fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions, + ): Acl = + // delete /v1/acl + withRawResponse().findAndDelete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AclService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: AclCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "acl") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * List out all acls. The acls are sorted by creation date, with the most recently-created acls - * coming first - */ - override fun list(params: AclListParams, requestOptions: RequestOptions): AclListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: AclRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "acl", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { AclListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete an acl object by its id */ - override fun delete(params: AclDeleteParams, requestOptions: RequestOptions): Acl { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "acl", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: AclListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "acl") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + .let { AclListPage.of(AclServiceImpl(clientOptions), params, it) } + } } - } - - private val batchUpdateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Batch update acls. This operation is idempotent, so adding acls which already exist will have - * no effect, and removing acls which do not exist will have no effect. - */ - override fun batchUpdate( - params: AclBatchUpdateParams, - requestOptions: RequestOptions - ): AclBatchUpdateResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "acl", "batch-update") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { batchUpdateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: AclDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "acl", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val findAndDeleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val batchUpdateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun batchUpdate( + params: AclBatchUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "acl", "batch_update") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { batchUpdateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } - /** Delete a single acl */ - override fun findAndDelete( - params: AclFindAndDeleteParams, - requestOptions: RequestOptions - ): Acl { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "acl") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { findAndDeleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val findAndDeleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun findAndDelete( + params: AclFindAndDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "acl") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { findAndDeleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretService.kt index a9445bf7..867aab8c 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.AISecret import com.braintrustdata.api.models.AiSecretCreateParams import com.braintrustdata.api.models.AiSecretDeleteParams @@ -14,24 +13,34 @@ import com.braintrustdata.api.models.AiSecretListParams import com.braintrustdata.api.models.AiSecretReplaceParams import com.braintrustdata.api.models.AiSecretRetrieveParams import com.braintrustdata.api.models.AiSecretUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface AiSecretService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new ai_secret. If there is an existing ai_secret with the same name as the one * specified in the request, will return the existing ai_secret unmodified */ - @JvmOverloads + fun create(params: AiSecretCreateParams): AISecret = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: AiSecretCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret /** Get an ai_secret object by its id */ - @JvmOverloads + fun retrieve(params: AiSecretRetrieveParams): AISecret = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: AiSecretRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret /** @@ -39,43 +48,181 @@ interface AiSecretService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: AiSecretUpdateParams): AISecret = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: AiSecretUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret /** * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most * recently-created ai_secrets coming first */ - @JvmOverloads + fun list(): AiSecretListPage = list(AiSecretListParams.none()) + + /** @see [list] */ fun list( - params: AiSecretListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: AiSecretListParams = AiSecretListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): AiSecretListPage + /** @see [list] */ + fun list(params: AiSecretListParams = AiSecretListParams.none()): AiSecretListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): AiSecretListPage = + list(AiSecretListParams.none(), requestOptions) + /** Delete an ai_secret object by its id */ - @JvmOverloads + fun delete(params: AiSecretDeleteParams): AISecret = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: AiSecretDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret /** Delete a single ai_secret */ - @JvmOverloads + fun findAndDelete(params: AiSecretFindAndDeleteParams): AISecret = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ fun findAndDelete( params: AiSecretFindAndDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret /** * Create or replace ai_secret. If there is an existing ai_secret with the same name as the one * specified in the request, will replace the existing ai_secret with the provided fields */ - @JvmOverloads + fun replace(params: AiSecretReplaceParams): AISecret = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: AiSecretReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): AISecret + + /** A view of [AiSecretService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/ai_secret`, but is otherwise the same as + * [AiSecretService.create]. + */ + @MustBeClosed + fun create(params: AiSecretCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: AiSecretCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/ai_secret/{ai_secret_id}`, but is otherwise the + * same as [AiSecretService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: AiSecretRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: AiSecretRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/ai_secret/{ai_secret_id}`, but is otherwise + * the same as [AiSecretService.update]. + */ + @MustBeClosed + fun update(params: AiSecretUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: AiSecretUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/ai_secret`, but is otherwise the same as + * [AiSecretService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(AiSecretListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: AiSecretListParams = AiSecretListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: AiSecretListParams = AiSecretListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(AiSecretListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/ai_secret/{ai_secret_id}`, but is otherwise + * the same as [AiSecretService.delete]. + */ + @MustBeClosed + fun delete(params: AiSecretDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: AiSecretDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `delete /v1/ai_secret`, but is otherwise the same as + * [AiSecretService.findAndDelete]. + */ + @MustBeClosed + fun findAndDelete(params: AiSecretFindAndDeleteParams): HttpResponseFor = + findAndDelete(params, RequestOptions.none()) + + /** @see [findAndDelete] */ + @MustBeClosed + fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/ai_secret`, but is otherwise the same as + * [AiSecretService.replace]. + */ + @MustBeClosed + fun replace(params: AiSecretReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: AiSecretReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceImpl.kt index 2b0fadbc..8824fdce 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.AISecret import com.braintrustdata.api.models.AiSecretCreateParams @@ -17,219 +24,245 @@ import com.braintrustdata.api.models.AiSecretListParams import com.braintrustdata.api.models.AiSecretReplaceParams import com.braintrustdata.api.models.AiSecretRetrieveParams import com.braintrustdata.api.models.AiSecretUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class AiSecretServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : AiSecretService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new ai_secret. If there is an existing ai_secret with the same name as the one - * specified in the request, will return the existing ai_secret unmodified - */ - override fun create(params: AiSecretCreateParams, requestOptions: RequestOptions): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } + +class AiSecretServiceImpl internal constructor(private val clientOptions: ClientOptions) : + AiSecretService { + + private val withRawResponse: AiSecretService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): AiSecretService.WithRawResponse = withRawResponse + + override fun create(params: AiSecretCreateParams, requestOptions: RequestOptions): AISecret = + // post /v1/ai_secret + withRawResponse().create(params, requestOptions).parse() - /** Get an ai_secret object by its id */ override fun retrieve( params: AiSecretRetrieveParams, - requestOptions: RequestOptions - ): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): AISecret = + // get /v1/ai_secret/{ai_secret_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: AiSecretUpdateParams, requestOptions: RequestOptions): AISecret = + // patch /v1/ai_secret/{ai_secret_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: AiSecretListParams, + requestOptions: RequestOptions, + ): AiSecretListPage = + // get /v1/ai_secret + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: AiSecretDeleteParams, requestOptions: RequestOptions): AISecret = + // delete /v1/ai_secret/{ai_secret_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions, + ): AISecret = + // delete /v1/ai_secret + withRawResponse().findAndDelete(params, requestOptions).parse() + + override fun replace(params: AiSecretReplaceParams, requestOptions: RequestOptions): AISecret = + // put /v1/ai_secret + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AiSecretService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: AiSecretCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update an ai_secret object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: AiSecretUpdateParams, requestOptions: RequestOptions): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: AiSecretRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * List out all ai_secrets. The ai_secrets are sorted by creation date, with the most - * recently-created ai_secrets coming first - */ - override fun list( - params: AiSecretListParams, - requestOptions: RequestOptions - ): AiSecretListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: AiSecretUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { AiSecretListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete an ai_secret object by its id */ - override fun delete(params: AiSecretDeleteParams, requestOptions: RequestOptions): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "ai_secret", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: AiSecretListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "ai_secret") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + .let { AiSecretListPage.of(AiSecretServiceImpl(clientOptions), params, it) } + } } - } - private val findAndDeleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete a single ai_secret */ - override fun findAndDelete( - params: AiSecretFindAndDeleteParams, - requestOptions: RequestOptions - ): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { findAndDeleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: AiSecretDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "ai_secret", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace ai_secret. If there is an existing ai_secret with the same name as the one - * specified in the request, will replace the existing ai_secret with the provided fields - */ - override fun replace(params: AiSecretReplaceParams, requestOptions: RequestOptions): AISecret { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "ai_secret") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val findAndDeleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun findAndDelete( + params: AiSecretFindAndDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { findAndDeleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: AiSecretReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "ai_secret") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyService.kt index a98e1d7e..7f07d4a8 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ApiKey import com.braintrustdata.api.models.ApiKeyCreateParams import com.braintrustdata.api.models.ApiKeyDeleteParams @@ -12,40 +11,136 @@ import com.braintrustdata.api.models.ApiKeyListPage import com.braintrustdata.api.models.ApiKeyListParams import com.braintrustdata.api.models.ApiKeyRetrieveParams import com.braintrustdata.api.models.CreateApiKeyOutput +import com.google.errorprone.annotations.MustBeClosed interface ApiKeyService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new api_key. It is possible to have multiple API keys with the same name. There is * no de-duplication */ - @JvmOverloads + fun create(params: ApiKeyCreateParams): CreateApiKeyOutput = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ApiKeyCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): CreateApiKeyOutput /** Get an api_key object by its id */ - @JvmOverloads + fun retrieve(params: ApiKeyRetrieveParams): ApiKey = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ApiKeyRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ApiKey /** * List out all api_keys. The api_keys are sorted by creation date, with the most * recently-created api_keys coming first */ - @JvmOverloads + fun list(): ApiKeyListPage = list(ApiKeyListParams.none()) + + /** @see [list] */ fun list( - params: ApiKeyListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ApiKeyListParams = ApiKeyListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): ApiKeyListPage + /** @see [list] */ + fun list(params: ApiKeyListParams = ApiKeyListParams.none()): ApiKeyListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): ApiKeyListPage = + list(ApiKeyListParams.none(), requestOptions) + /** Delete an api_key object by its id */ - @JvmOverloads + fun delete(params: ApiKeyDeleteParams): ApiKey = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ApiKeyDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ApiKey + + /** A view of [ApiKeyService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/api_key`, but is otherwise the same as + * [ApiKeyService.create]. + */ + @MustBeClosed + fun create(params: ApiKeyCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ApiKeyCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/api_key/{api_key_id}`, but is otherwise the same + * as [ApiKeyService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ApiKeyRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ApiKeyRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/api_key`, but is otherwise the same as + * [ApiKeyService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(ApiKeyListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ApiKeyListParams = ApiKeyListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: ApiKeyListParams = ApiKeyListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(ApiKeyListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/api_key/{api_key_id}`, but is otherwise the + * same as [ApiKeyService.delete]. + */ + @MustBeClosed + fun delete(params: ApiKeyDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ApiKeyDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceImpl.kt index 5b705c68..cba100a5 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ApiKey import com.braintrustdata.api.models.ApiKeyCreateParams @@ -15,128 +22,146 @@ import com.braintrustdata.api.models.ApiKeyListPage import com.braintrustdata.api.models.ApiKeyListParams import com.braintrustdata.api.models.ApiKeyRetrieveParams import com.braintrustdata.api.models.CreateApiKeyOutput -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class ApiKeyServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ApiKeyService { +class ApiKeyServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ApiKeyService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ApiKeyService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ApiKeyService.WithRawResponse = withRawResponse - /** - * Create a new api_key. It is possible to have multiple API keys with the same name. There is - * no de-duplication - */ override fun create( params: ApiKeyCreateParams, - requestOptions: RequestOptions - ): CreateApiKeyOutput { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "api_key") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): CreateApiKeyOutput = + // post /v1/api_key + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: ApiKeyRetrieveParams, requestOptions: RequestOptions): ApiKey = + // get /v1/api_key/{api_key_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun list(params: ApiKeyListParams, requestOptions: RequestOptions): ApiKeyListPage = + // get /v1/api_key + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: ApiKeyDeleteParams, requestOptions: RequestOptions): ApiKey = + // delete /v1/api_key/{api_key_id} + withRawResponse().delete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ApiKeyService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ApiKeyCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "api_key") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get an api_key object by its id */ - override fun retrieve(params: ApiKeyRetrieveParams, requestOptions: RequestOptions): ApiKey { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "api_key", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ApiKeyRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "api_key", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * List out all api_keys. The api_keys are sorted by creation date, with the most - * recently-created api_keys coming first - */ - override fun list(params: ApiKeyListParams, requestOptions: RequestOptions): ApiKeyListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "api_key") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ApiKeyListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "api_key") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ApiKeyListPage.of(this, params, it) } + .let { ApiKeyListPage.of(ApiKeyServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete an api_key object by its id */ - override fun delete(params: ApiKeyDeleteParams, requestOptions: RequestOptions): ApiKey { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "api_key", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ApiKeyDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "api_key", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetService.kt index 418bb13a..91a18478 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Dataset import com.braintrustdata.api.models.DatasetCreateParams import com.braintrustdata.api.models.DatasetDeleteParams @@ -21,24 +20,34 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchDatasetEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeDatasetResponse +import com.google.errorprone.annotations.MustBeClosed interface DatasetService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new dataset. If there is an existing dataset in the project with the same name as * the one specified in the request, will return the existing dataset unmodified */ - @JvmOverloads + fun create(params: DatasetCreateParams): Dataset = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: DatasetCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Dataset /** Get a dataset object by its id */ - @JvmOverloads + fun retrieve(params: DatasetRetrieveParams): Dataset = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: DatasetRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Dataset /** @@ -46,67 +55,261 @@ interface DatasetService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: DatasetUpdateParams): Dataset = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: DatasetUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Dataset /** * List out all datasets. The datasets are sorted by creation date, with the most * recently-created datasets coming first */ - @JvmOverloads + fun list(): DatasetListPage = list(DatasetListParams.none()) + + /** @see [list] */ fun list( - params: DatasetListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: DatasetListParams = DatasetListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): DatasetListPage + /** @see [list] */ + fun list(params: DatasetListParams = DatasetListParams.none()): DatasetListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): DatasetListPage = + list(DatasetListParams.none(), requestOptions) + /** Delete a dataset object by its id */ - @JvmOverloads + fun delete(params: DatasetDeleteParams): Dataset = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: DatasetDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Dataset /** Log feedback for a set of dataset events */ - @JvmOverloads + fun feedback(params: DatasetFeedbackParams): FeedbackResponseSchema = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: DatasetFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FeedbackResponseSchema /** * Fetch the events in a dataset. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body + * parameters in the URL query rather than in the request body. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: DatasetFetchParams): FetchDatasetEventsResponse = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: DatasetFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchDatasetEventsResponse /** * Fetch the events in a dataset. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost(params: DatasetFetchPostParams): FetchDatasetEventsResponse = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: DatasetFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchDatasetEventsResponse /** Insert a set of events into the dataset */ - @JvmOverloads + fun insert(params: DatasetInsertParams): InsertEventsResponse = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: DatasetInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): InsertEventsResponse /** Summarize dataset */ - @JvmOverloads + fun summarize(params: DatasetSummarizeParams): SummarizeDatasetResponse = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ fun summarize( params: DatasetSummarizeParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): SummarizeDatasetResponse + + /** A view of [DatasetService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/dataset`, but is otherwise the same as + * [DatasetService.create]. + */ + @MustBeClosed + fun create(params: DatasetCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: DatasetCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}`, but is otherwise the same + * as [DatasetService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: DatasetRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: DatasetRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/dataset/{dataset_id}`, but is otherwise the + * same as [DatasetService.update]. + */ + @MustBeClosed + fun update(params: DatasetUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: DatasetUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/dataset`, but is otherwise the same as + * [DatasetService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(DatasetListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: DatasetListParams = DatasetListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: DatasetListParams = DatasetListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(DatasetListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/dataset/{dataset_id}`, but is otherwise the + * same as [DatasetService.delete]. + */ + @MustBeClosed + fun delete(params: DatasetDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: DatasetDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/feedback`, but is + * otherwise the same as [DatasetService.feedback]. + */ + @MustBeClosed + fun feedback(params: DatasetFeedbackParams): HttpResponseFor = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}/fetch`, but is otherwise + * the same as [DatasetService.fetch]. + */ + @MustBeClosed + fun fetch(params: DatasetFetchParams): HttpResponseFor = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/fetch`, but is otherwise + * the same as [DatasetService.fetchPost]. + */ + @MustBeClosed + fun fetchPost(params: DatasetFetchPostParams): HttpResponseFor = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/dataset/{dataset_id}/insert`, but is otherwise + * the same as [DatasetService.insert]. + */ + @MustBeClosed + fun insert(params: DatasetInsertParams): HttpResponseFor = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/dataset/{dataset_id}/summarize`, but is + * otherwise the same as [DatasetService.summarize]. + */ + @MustBeClosed + fun summarize(params: DatasetSummarizeParams): HttpResponseFor = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ + @MustBeClosed + fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceImpl.kt index a7d2f6e1..033ed993 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Dataset import com.braintrustdata.api.models.DatasetCreateParams @@ -24,307 +31,347 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchDatasetEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeDatasetResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class DatasetServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : DatasetService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new dataset. If there is an existing dataset in the project with the same name as - * the one specified in the request, will return the existing dataset unmodified - */ - override fun create(params: DatasetCreateParams, requestOptions: RequestOptions): Dataset { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + +class DatasetServiceImpl internal constructor(private val clientOptions: ClientOptions) : + DatasetService { + + private val withRawResponse: DatasetService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): DatasetService.WithRawResponse = withRawResponse + + override fun create(params: DatasetCreateParams, requestOptions: RequestOptions): Dataset = + // post /v1/dataset + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: DatasetRetrieveParams, requestOptions: RequestOptions): Dataset = + // get /v1/dataset/{dataset_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: DatasetUpdateParams, requestOptions: RequestOptions): Dataset = + // patch /v1/dataset/{dataset_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: DatasetListParams, requestOptions: RequestOptions): DatasetListPage = + // get /v1/dataset + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: DatasetDeleteParams, requestOptions: RequestOptions): Dataset = + // delete /v1/dataset/{dataset_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions, + ): FeedbackResponseSchema = + // post /v1/dataset/{dataset_id}/feedback + withRawResponse().feedback(params, requestOptions).parse() + + override fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions, + ): FetchDatasetEventsResponse = + // get /v1/dataset/{dataset_id}/fetch + withRawResponse().fetch(params, requestOptions).parse() + + override fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions, + ): FetchDatasetEventsResponse = + // post /v1/dataset/{dataset_id}/fetch + withRawResponse().fetchPost(params, requestOptions).parse() + + override fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions, + ): InsertEventsResponse = + // post /v1/dataset/{dataset_id}/insert + withRawResponse().insert(params, requestOptions).parse() + + override fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions, + ): SummarizeDatasetResponse = + // get /v1/dataset/{dataset_id}/summarize + withRawResponse().summarize(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + DatasetService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: DatasetCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a dataset object by its id */ - override fun retrieve(params: DatasetRetrieveParams, requestOptions: RequestOptions): Dataset { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: DatasetRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a dataset object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: DatasetUpdateParams, requestOptions: RequestOptions): Dataset { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: DatasetUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * List out all datasets. The datasets are sorted by creation date, with the most - * recently-created datasets coming first - */ - override fun list(params: DatasetListParams, requestOptions: RequestOptions): DatasetListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: DatasetListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { DatasetListPage.of(this, params, it) } + .let { DatasetListPage.of(DatasetServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a dataset object by its id */ - override fun delete(params: DatasetDeleteParams, requestOptions: RequestOptions): Dataset { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "dataset", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: DatasetDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "dataset", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Log feedback for a set of dataset events */ - override fun feedback( - params: DatasetFeedbackParams, - requestOptions: RequestOptions - ): FeedbackResponseSchema { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun feedback( + params: DatasetFeedbackParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a dataset. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body - */ - override fun fetch( - params: DatasetFetchParams, - requestOptions: RequestOptions - ): FetchDatasetEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: DatasetFetchParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a dataset. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: DatasetFetchPostParams, - requestOptions: RequestOptions - ): FetchDatasetEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: DatasetFetchPostParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the dataset */ - override fun insert( - params: DatasetInsertParams, - requestOptions: RequestOptions - ): InsertEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "dataset", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: DatasetInsertParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "dataset", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val summarizeHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val summarizeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Summarize dataset */ - override fun summarize( - params: DatasetSummarizeParams, - requestOptions: RequestOptions - ): SummarizeDatasetResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "dataset", params.getPathParam(0), "summarize") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { summarizeHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun summarize( + params: DatasetSummarizeParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "dataset", params.getPathParam(0), "summarize") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { summarizeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarService.kt index 5162047c..843a4762 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.EnvVar import com.braintrustdata.api.models.EnvVarCreateParams import com.braintrustdata.api.models.EnvVarDeleteParams @@ -13,24 +12,34 @@ import com.braintrustdata.api.models.EnvVarListResponse import com.braintrustdata.api.models.EnvVarReplaceParams import com.braintrustdata.api.models.EnvVarRetrieveParams import com.braintrustdata.api.models.EnvVarUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface EnvVarService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new env_var. If there is an existing env_var with the same name as the one specified * in the request, will return the existing env_var unmodified */ - @JvmOverloads + fun create(params: EnvVarCreateParams): EnvVar = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: EnvVarCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVar /** Get an env_var object by its id */ - @JvmOverloads + fun retrieve(params: EnvVarRetrieveParams): EnvVar = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: EnvVarRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVar /** @@ -38,36 +47,156 @@ interface EnvVarService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: EnvVarUpdateParams): EnvVar = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: EnvVarUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVar /** * List out all env_vars. The env_vars are sorted by creation date, with the most * recently-created env_vars coming first */ - @JvmOverloads + fun list(): EnvVarListResponse = list(EnvVarListParams.none()) + + /** @see [list] */ fun list( - params: EnvVarListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: EnvVarListParams = EnvVarListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVarListResponse + /** @see [list] */ + fun list(params: EnvVarListParams = EnvVarListParams.none()): EnvVarListResponse = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): EnvVarListResponse = + list(EnvVarListParams.none(), requestOptions) + /** Delete an env_var object by its id */ - @JvmOverloads + fun delete(params: EnvVarDeleteParams): EnvVar = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: EnvVarDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVar /** * Create or replace env_var. If there is an existing env_var with the same name as the one * specified in the request, will replace the existing env_var with the provided fields */ - @JvmOverloads + fun replace(params: EnvVarReplaceParams): EnvVar = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: EnvVarReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): EnvVar + + /** A view of [EnvVarService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/env_var`, but is otherwise the same as + * [EnvVarService.create]. + */ + @MustBeClosed + fun create(params: EnvVarCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: EnvVarCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/env_var/{env_var_id}`, but is otherwise the same + * as [EnvVarService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: EnvVarRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: EnvVarRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/env_var/{env_var_id}`, but is otherwise the + * same as [EnvVarService.update]. + */ + @MustBeClosed + fun update(params: EnvVarUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: EnvVarUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/env_var`, but is otherwise the same as + * [EnvVarService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(EnvVarListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: EnvVarListParams = EnvVarListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: EnvVarListParams = EnvVarListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(EnvVarListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/env_var/{env_var_id}`, but is otherwise the + * same as [EnvVarService.delete]. + */ + @MustBeClosed + fun delete(params: EnvVarDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: EnvVarDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/env_var`, but is otherwise the same as + * [EnvVarService.replace]. + */ + @MustBeClosed + fun replace(params: EnvVarReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: EnvVarReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceImpl.kt index 947656fd..aa611b8f 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.EnvVar import com.braintrustdata.api.models.EnvVarCreateParams @@ -16,185 +23,206 @@ import com.braintrustdata.api.models.EnvVarListResponse import com.braintrustdata.api.models.EnvVarReplaceParams import com.braintrustdata.api.models.EnvVarRetrieveParams import com.braintrustdata.api.models.EnvVarUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class EnvVarServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : EnvVarService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new env_var. If there is an existing env_var with the same name as the one specified - * in the request, will return the existing env_var unmodified - */ - override fun create(params: EnvVarCreateParams, requestOptions: RequestOptions): EnvVar { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } + +class EnvVarServiceImpl internal constructor(private val clientOptions: ClientOptions) : + EnvVarService { + + private val withRawResponse: EnvVarService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get an env_var object by its id */ - override fun retrieve(params: EnvVarRetrieveParams, requestOptions: RequestOptions): EnvVar { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun withRawResponse(): EnvVarService.WithRawResponse = withRawResponse + + override fun create(params: EnvVarCreateParams, requestOptions: RequestOptions): EnvVar = + // post /v1/env_var + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: EnvVarRetrieveParams, requestOptions: RequestOptions): EnvVar = + // get /v1/env_var/{env_var_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: EnvVarUpdateParams, requestOptions: RequestOptions): EnvVar = + // patch /v1/env_var/{env_var_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: EnvVarListParams, + requestOptions: RequestOptions, + ): EnvVarListResponse = + // get /v1/env_var + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: EnvVarDeleteParams, requestOptions: RequestOptions): EnvVar = + // delete /v1/env_var/{env_var_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace(params: EnvVarReplaceParams, requestOptions: RequestOptions): EnvVar = + // put /v1/env_var + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EnvVarService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: EnvVarCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "env_var") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update an env_var object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: EnvVarUpdateParams, requestOptions: RequestOptions): EnvVar { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: EnvVarRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: EnvVarUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } - /** - * List out all env_vars. The env_vars are sorted by creation date, with the most - * recently-created env_vars coming first - */ - override fun list( - params: EnvVarListParams, - requestOptions: RequestOptions - ): EnvVarListResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun list( + params: EnvVarListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "env_var") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete an env_var object by its id */ - override fun delete(params: EnvVarDeleteParams, requestOptions: RequestOptions): EnvVar { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "env_var", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: EnvVarDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "env_var", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace env_var. If there is an existing env_var with the same name as the one - * specified in the request, will replace the existing env_var with the provided fields - */ - override fun replace(params: EnvVarReplaceParams, requestOptions: RequestOptions): EnvVar { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "env_var") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: EnvVarReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "env_var") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalService.kt index 54249924..fa1bcc99 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalService.kt @@ -1,15 +1,20 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.EvalCreateParams import com.braintrustdata.api.models.SummarizeExperimentResponse +import com.google.errorprone.annotations.MustBeClosed interface EvalService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Launch an evaluation. This is the API-equivalent of the `Eval` function that is built into * the Braintrust SDK. In the Eval API, you provide pointers to a dataset, task function, and @@ -17,9 +22,31 @@ interface EvalService { * results along with a link to the experiment. To learn more about evals, see the * [Evals guide](https://www.braintrust.dev/docs/guides/evals). */ - @JvmOverloads + fun create(params: EvalCreateParams): SummarizeExperimentResponse = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: EvalCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): SummarizeExperimentResponse + + /** A view of [EvalService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/eval`, but is otherwise the same as + * [EvalService.create]. + */ + @MustBeClosed + fun create(params: EvalCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: EvalCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalServiceImpl.kt index 2811b4d7..e761eba5 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/EvalServiceImpl.kt @@ -4,57 +4,66 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.EvalCreateParams import com.braintrustdata.api.models.SummarizeExperimentResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class EvalServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : EvalService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * Launch an evaluation. This is the API-equivalent of the `Eval` function that is built into - * the Braintrust SDK. In the Eval API, you provide pointers to a dataset, task function, and - * scoring functions. The API will then run the evaluation, create an experiment, and return the - * results along with a link to the experiment. To learn more about evals, see the - * [Evals guide](https://www.braintrust.dev/docs/guides/evals). - */ + +class EvalServiceImpl internal constructor(private val clientOptions: ClientOptions) : EvalService { + + private val withRawResponse: EvalService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): EvalService.WithRawResponse = withRawResponse + override fun create( params: EvalCreateParams, - requestOptions: RequestOptions - ): SummarizeExperimentResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "eval") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): SummarizeExperimentResponse = + // post /v1/eval + withRawResponse().create(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EvalService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun create( + params: EvalCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "eval") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentService.kt index daf9bb69..17bc351f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Experiment import com.braintrustdata.api.models.ExperimentCreateParams import com.braintrustdata.api.models.ExperimentDeleteParams @@ -21,24 +20,35 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchExperimentEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeExperimentResponse +import com.google.errorprone.annotations.MustBeClosed interface ExperimentService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new experiment. If there is an existing experiment in the project with the same name * as the one specified in the request, will return the existing experiment unmodified */ - @JvmOverloads + fun create(params: ExperimentCreateParams): Experiment = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ExperimentCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Experiment /** Get an experiment object by its id */ - @JvmOverloads + fun retrieve(params: ExperimentRetrieveParams): Experiment = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ExperimentRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Experiment /** @@ -46,67 +56,264 @@ interface ExperimentService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ExperimentUpdateParams): Experiment = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ExperimentUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Experiment /** * List out all experiments. The experiments are sorted by creation date, with the most * recently-created experiments coming first */ - @JvmOverloads + fun list(): ExperimentListPage = list(ExperimentListParams.none()) + + /** @see [list] */ fun list( - params: ExperimentListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ExperimentListParams = ExperimentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): ExperimentListPage + /** @see [list] */ + fun list(params: ExperimentListParams = ExperimentListParams.none()): ExperimentListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): ExperimentListPage = + list(ExperimentListParams.none(), requestOptions) + /** Delete an experiment object by its id */ - @JvmOverloads + fun delete(params: ExperimentDeleteParams): Experiment = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ExperimentDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Experiment /** Log feedback for a set of experiment events */ - @JvmOverloads + fun feedback(params: ExperimentFeedbackParams): FeedbackResponseSchema = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: ExperimentFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FeedbackResponseSchema /** * Fetch the events in an experiment. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body + * parameters in the URL query rather than in the request body. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: ExperimentFetchParams): FetchExperimentEventsResponse = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: ExperimentFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchExperimentEventsResponse /** * Fetch the events in an experiment. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost(params: ExperimentFetchPostParams): FetchExperimentEventsResponse = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: ExperimentFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchExperimentEventsResponse /** Insert a set of events into the experiment */ - @JvmOverloads + fun insert(params: ExperimentInsertParams): InsertEventsResponse = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: ExperimentInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): InsertEventsResponse /** Summarize experiment */ - @JvmOverloads + fun summarize(params: ExperimentSummarizeParams): SummarizeExperimentResponse = + summarize(params, RequestOptions.none()) + + /** @see [summarize] */ fun summarize( params: ExperimentSummarizeParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): SummarizeExperimentResponse + + /** A view of [ExperimentService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/experiment`, but is otherwise the same as + * [ExperimentService.create]. + */ + @MustBeClosed + fun create(params: ExperimentCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ExperimentCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ExperimentRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentService.update]. + */ + @MustBeClosed + fun update(params: ExperimentUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/experiment`, but is otherwise the same as + * [ExperimentService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(ExperimentListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ExperimentListParams = ExperimentListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: ExperimentListParams = ExperimentListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(ExperimentListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/experiment/{experiment_id}`, but is otherwise + * the same as [ExperimentService.delete]. + */ + @MustBeClosed + fun delete(params: ExperimentDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/feedback`, but is + * otherwise the same as [ExperimentService.feedback]. + */ + @MustBeClosed + fun feedback(params: ExperimentFeedbackParams): HttpResponseFor = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}/fetch`, but is + * otherwise the same as [ExperimentService.fetch]. + */ + @MustBeClosed + fun fetch(params: ExperimentFetchParams): HttpResponseFor = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/fetch`, but is + * otherwise the same as [ExperimentService.fetchPost]. + */ + @MustBeClosed + fun fetchPost( + params: ExperimentFetchPostParams + ): HttpResponseFor = fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/experiment/{experiment_id}/insert`, but is + * otherwise the same as [ExperimentService.insert]. + */ + @MustBeClosed + fun insert(params: ExperimentInsertParams): HttpResponseFor = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/experiment/{experiment_id}/summarize`, but is + * otherwise the same as [ExperimentService.summarize]. + */ + @MustBeClosed + fun summarize( + params: ExperimentSummarizeParams + ): HttpResponseFor = summarize(params, RequestOptions.none()) + + /** @see [summarize] */ + @MustBeClosed + fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceImpl.kt index 1d80270a..7ec0526e 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Experiment import com.braintrustdata.api.models.ExperimentCreateParams @@ -24,322 +31,362 @@ import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchExperimentEventsResponse import com.braintrustdata.api.models.InsertEventsResponse import com.braintrustdata.api.models.SummarizeExperimentResponse -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class ExperimentServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ExperimentService { +class ExperimentServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ExperimentService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ExperimentService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ExperimentService.WithRawResponse = withRawResponse - /** - * Create a new experiment. If there is an existing experiment in the project with the same name - * as the one specified in the request, will return the existing experiment unmodified - */ override fun create( params: ExperimentCreateParams, - requestOptions: RequestOptions - ): Experiment { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): Experiment = + // post /v1/experiment + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions, + ): Experiment = + // get /v1/experiment/{experiment_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions, + ): Experiment = + // patch /v1/experiment/{experiment_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: ExperimentListParams, + requestOptions: RequestOptions, + ): ExperimentListPage = + // get /v1/experiment + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions, + ): Experiment = + // delete /v1/experiment/{experiment_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions, + ): FeedbackResponseSchema = + // post /v1/experiment/{experiment_id}/feedback + withRawResponse().feedback(params, requestOptions).parse() + + override fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions, + ): FetchExperimentEventsResponse = + // get /v1/experiment/{experiment_id}/fetch + withRawResponse().fetch(params, requestOptions).parse() + + override fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions, + ): FetchExperimentEventsResponse = + // post /v1/experiment/{experiment_id}/fetch + withRawResponse().fetchPost(params, requestOptions).parse() + + override fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions, + ): InsertEventsResponse = + // post /v1/experiment/{experiment_id}/insert + withRawResponse().insert(params, requestOptions).parse() + + override fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions, + ): SummarizeExperimentResponse = + // get /v1/experiment/{experiment_id}/summarize + withRawResponse().summarize(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ExperimentService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ExperimentCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Get an experiment object by its id */ - override fun retrieve( - params: ExperimentRetrieveParams, - requestOptions: RequestOptions - ): Experiment { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun retrieve( + params: ExperimentRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an experiment object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: ExperimentUpdateParams, - requestOptions: RequestOptions - ): Experiment { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: ExperimentUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all experiments. The experiments are sorted by creation date, with the most - * recently-created experiments coming first - */ - override fun list( - params: ExperimentListParams, - requestOptions: RequestOptions - ): ExperimentListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: ExperimentListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ExperimentListPage.of(this, params, it) } + .let { ExperimentListPage.of(ExperimentServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an experiment object by its id */ - override fun delete( - params: ExperimentDeleteParams, - requestOptions: RequestOptions - ): Experiment { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "experiment", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: ExperimentDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "experiment", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Log feedback for a set of experiment events */ - override fun feedback( - params: ExperimentFeedbackParams, - requestOptions: RequestOptions - ): FeedbackResponseSchema { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun feedback( + params: ExperimentFeedbackParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in an experiment. Equivalent to the POST form of the same path, but with the - * parameters in the URL query rather than in the request body - */ - override fun fetch( - params: ExperimentFetchParams, - requestOptions: RequestOptions - ): FetchExperimentEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: ExperimentFetchParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in an experiment. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: ExperimentFetchPostParams, - requestOptions: RequestOptions - ): FetchExperimentEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: ExperimentFetchPostParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the experiment */ - override fun insert( - params: ExperimentInsertParams, - requestOptions: RequestOptions - ): InsertEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "experiment", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: ExperimentInsertParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "experiment", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val summarizeHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val summarizeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Summarize experiment */ - override fun summarize( - params: ExperimentSummarizeParams, - requestOptions: RequestOptions - ): SummarizeExperimentResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "experiment", params.getPathParam(0), "summarize") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { summarizeHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun summarize( + params: ExperimentSummarizeParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "experiment", params.getPathParam(0), "summarize") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { summarizeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionService.kt index 12d58d53..2002b104 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Function import com.braintrustdata.api.models.FunctionCreateParams import com.braintrustdata.api.models.FunctionDeleteParams @@ -15,24 +14,35 @@ import com.braintrustdata.api.models.FunctionListParams import com.braintrustdata.api.models.FunctionReplaceParams import com.braintrustdata.api.models.FunctionRetrieveParams import com.braintrustdata.api.models.FunctionUpdateParams +import com.google.errorprone.annotations.MustBeClosed +import java.util.Optional interface FunctionService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new function. If there is an existing function in the project with the same slug as * the one specified in the request, will return the existing function unmodified */ - @JvmOverloads + fun create(params: FunctionCreateParams): Function = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: FunctionCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Function /** Get a function object by its id */ - @JvmOverloads + fun retrieve(params: FunctionRetrieveParams): Function = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: FunctionRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Function /** @@ -40,44 +50,183 @@ interface FunctionService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: FunctionUpdateParams): Function = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: FunctionUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Function /** * List out all functions. The functions are sorted by creation date, with the most * recently-created functions coming first */ - @JvmOverloads + fun list(): FunctionListPage = list(FunctionListParams.none()) + + /** @see [list] */ fun list( - params: FunctionListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: FunctionListParams = FunctionListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): FunctionListPage + /** @see [list] */ + fun list(params: FunctionListParams = FunctionListParams.none()): FunctionListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): FunctionListPage = + list(FunctionListParams.none(), requestOptions) + /** Delete a function object by its id */ - @JvmOverloads + fun delete(params: FunctionDeleteParams): Function = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: FunctionDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Function /** Invoke a function. */ - @JvmOverloads + fun invoke(params: FunctionInvokeParams): Optional = + invoke(params, RequestOptions.none()) + + /** @see [invoke] */ fun invoke( params: FunctionInvokeParams, - requestOptions: RequestOptions = RequestOptions.none() - ): FunctionInvokeResponse + requestOptions: RequestOptions = RequestOptions.none(), + ): Optional /** * Create or replace function. If there is an existing function in the project with the same * slug as the one specified in the request, will replace the existing function with the * provided fields */ - @JvmOverloads + fun replace(params: FunctionReplaceParams): Function = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: FunctionReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Function + + /** A view of [FunctionService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/function`, but is otherwise the same as + * [FunctionService.create]. + */ + @MustBeClosed + fun create(params: FunctionCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: FunctionCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/function/{function_id}`, but is otherwise the + * same as [FunctionService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: FunctionRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: FunctionRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/function/{function_id}`, but is otherwise the + * same as [FunctionService.update]. + */ + @MustBeClosed + fun update(params: FunctionUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: FunctionUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/function`, but is otherwise the same as + * [FunctionService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(FunctionListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: FunctionListParams = FunctionListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: FunctionListParams = FunctionListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(FunctionListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/function/{function_id}`, but is otherwise the + * same as [FunctionService.delete]. + */ + @MustBeClosed + fun delete(params: FunctionDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: FunctionDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/function/{function_id}/invoke`, but is + * otherwise the same as [FunctionService.invoke]. + */ + @MustBeClosed + fun invoke( + params: FunctionInvokeParams + ): HttpResponseFor> = invoke(params, RequestOptions.none()) + + /** @see [invoke] */ + @MustBeClosed + fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor> + + /** + * Returns a raw HTTP response for `put /v1/function`, but is otherwise the same as + * [FunctionService.replace]. + */ + @MustBeClosed + fun replace(params: FunctionReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: FunctionReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceImpl.kt index d626758d..cf7eb4ad 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Function import com.braintrustdata.api.models.FunctionCreateParams @@ -18,214 +25,247 @@ import com.braintrustdata.api.models.FunctionListParams import com.braintrustdata.api.models.FunctionReplaceParams import com.braintrustdata.api.models.FunctionRetrieveParams import com.braintrustdata.api.models.FunctionUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class FunctionServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : FunctionService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new function. If there is an existing function in the project with the same slug as - * the one specified in the request, will return the existing function unmodified - */ - override fun create(params: FunctionCreateParams, requestOptions: RequestOptions): Function { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } +import java.util.Optional + +class FunctionServiceImpl internal constructor(private val clientOptions: ClientOptions) : + FunctionService { + + private val withRawResponse: FunctionService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): FunctionService.WithRawResponse = withRawResponse + + override fun create(params: FunctionCreateParams, requestOptions: RequestOptions): Function = + // post /v1/function + withRawResponse().create(params, requestOptions).parse() - /** Get a function object by its id */ override fun retrieve( params: FunctionRetrieveParams, - requestOptions: RequestOptions - ): Function { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): Function = + // get /v1/function/{function_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: FunctionUpdateParams, requestOptions: RequestOptions): Function = + // patch /v1/function/{function_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: FunctionListParams, + requestOptions: RequestOptions, + ): FunctionListPage = + // get /v1/function + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: FunctionDeleteParams, requestOptions: RequestOptions): Function = + // delete /v1/function/{function_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions, + ): Optional = + // post /v1/function/{function_id}/invoke + withRawResponse().invoke(params, requestOptions).parse() + + override fun replace(params: FunctionReplaceParams, requestOptions: RequestOptions): Function = + // put /v1/function + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + FunctionService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: FunctionCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "function") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a function object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: FunctionUpdateParams, requestOptions: RequestOptions): Function { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: FunctionRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "function", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * List out all functions. The functions are sorted by creation date, with the most - * recently-created functions coming first - */ - override fun list( - params: FunctionListParams, - requestOptions: RequestOptions - ): FunctionListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: FunctionUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "function", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { FunctionListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a function object by its id */ - override fun delete(params: FunctionDeleteParams, requestOptions: RequestOptions): Function { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "function", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: FunctionListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "function") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + .let { FunctionListPage.of(FunctionServiceImpl(clientOptions), params, it) } + } } - } - private val invokeHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Invoke a function. */ - override fun invoke( - params: FunctionInvokeParams, - requestOptions: RequestOptions - ): FunctionInvokeResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "function", params.getPathParam(0), "invoke") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response.use { invokeHandler.handle(it) } + override fun delete( + params: FunctionDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "function", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace function. If there is an existing function in the project with the same - * slug as the one specified in the request, will replace the existing function with the - * provided fields - */ - override fun replace(params: FunctionReplaceParams, requestOptions: RequestOptions): Function { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "function") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val invokeHandler: Handler> = + jsonHandler>(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun invoke( + params: FunctionInvokeParams, + requestOptions: RequestOptions, + ): HttpResponseFor> { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "function", params.getPathParam(0), "invoke") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { invokeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.ifPresent { it.validate() } + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: FunctionReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "function") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupService.kt index 2b544c2e..5249cbc6 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Group import com.braintrustdata.api.models.GroupCreateParams import com.braintrustdata.api.models.GroupDeleteParams @@ -13,24 +12,34 @@ import com.braintrustdata.api.models.GroupListParams import com.braintrustdata.api.models.GroupReplaceParams import com.braintrustdata.api.models.GroupRetrieveParams import com.braintrustdata.api.models.GroupUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface GroupService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new group. If there is an existing group with the same name as the one specified in * the request, will return the existing group unmodified */ - @JvmOverloads + fun create(params: GroupCreateParams): Group = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: GroupCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Group /** Get a group object by its id */ - @JvmOverloads + fun retrieve(params: GroupRetrieveParams): Group = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: GroupRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Group /** @@ -38,36 +47,154 @@ interface GroupService { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: GroupUpdateParams): Group = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: GroupUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Group /** * List out all groups. The groups are sorted by creation date, with the most recently-created * groups coming first */ - @JvmOverloads + fun list(): GroupListPage = list(GroupListParams.none()) + + /** @see [list] */ fun list( - params: GroupListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: GroupListParams = GroupListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): GroupListPage + /** @see [list] */ + fun list(params: GroupListParams = GroupListParams.none()): GroupListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): GroupListPage = + list(GroupListParams.none(), requestOptions) + /** Delete a group object by its id */ - @JvmOverloads + fun delete(params: GroupDeleteParams): Group = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: GroupDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Group /** * Create or replace group. If there is an existing group with the same name as the one * specified in the request, will replace the existing group with the provided fields */ - @JvmOverloads + fun replace(params: GroupReplaceParams): Group = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: GroupReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Group + + /** A view of [GroupService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/group`, but is otherwise the same as + * [GroupService.create]. + */ + @MustBeClosed + fun create(params: GroupCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: GroupCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/group/{group_id}`, but is otherwise the same as + * [GroupService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: GroupRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: GroupRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/group/{group_id}`, but is otherwise the same + * as [GroupService.update]. + */ + @MustBeClosed + fun update(params: GroupUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: GroupUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/group`, but is otherwise the same as + * [GroupService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(GroupListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: GroupListParams = GroupListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: GroupListParams = GroupListParams.none()): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(GroupListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/group/{group_id}`, but is otherwise the same + * as [GroupService.delete]. + */ + @MustBeClosed + fun delete(params: GroupDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: GroupDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/group`, but is otherwise the same as + * [GroupService.replace]. + */ + @MustBeClosed + fun replace(params: GroupReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: GroupReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupServiceImpl.kt index 352a97e9..84a146af 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/GroupServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Group import com.braintrustdata.api.models.GroupCreateParams @@ -16,183 +23,205 @@ import com.braintrustdata.api.models.GroupListParams import com.braintrustdata.api.models.GroupReplaceParams import com.braintrustdata.api.models.GroupRetrieveParams import com.braintrustdata.api.models.GroupUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class GroupServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : GroupService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new group. If there is an existing group with the same name as the one specified in - * the request, will return the existing group unmodified - */ - override fun create(params: GroupCreateParams, requestOptions: RequestOptions): Group { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + +class GroupServiceImpl internal constructor(private val clientOptions: ClientOptions) : + GroupService { + + private val withRawResponse: GroupService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): GroupService.WithRawResponse = withRawResponse + + override fun create(params: GroupCreateParams, requestOptions: RequestOptions): Group = + // post /v1/group + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: GroupRetrieveParams, requestOptions: RequestOptions): Group = + // get /v1/group/{group_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: GroupUpdateParams, requestOptions: RequestOptions): Group = + // patch /v1/group/{group_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: GroupListParams, requestOptions: RequestOptions): GroupListPage = + // get /v1/group + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: GroupDeleteParams, requestOptions: RequestOptions): Group = + // delete /v1/group/{group_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace(params: GroupReplaceParams, requestOptions: RequestOptions): Group = + // put /v1/group + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + GroupService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: GroupCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "group") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a group object by its id */ - override fun retrieve(params: GroupRetrieveParams, requestOptions: RequestOptions): Group { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: GroupRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "group", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a group object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update(params: GroupUpdateParams, requestOptions: RequestOptions): Group { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: GroupUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "group", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * List out all groups. The groups are sorted by creation date, with the most recently-created - * groups coming first - */ - override fun list(params: GroupListParams, requestOptions: RequestOptions): GroupListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: GroupListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "group") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { GroupListPage.of(this, params, it) } + .let { GroupListPage.of(GroupServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a group object by its id */ - override fun delete(params: GroupDeleteParams, requestOptions: RequestOptions): Group { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "group", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: GroupDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "group", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace group. If there is an existing group with the same name as the one - * specified in the request, will replace the existing group with the provided fields - */ - override fun replace(params: GroupReplaceParams, requestOptions: RequestOptions): Group { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "group") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: GroupReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "group") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationService.kt index f4ca1ae2..b2ddae2c 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Organization import com.braintrustdata.api.models.OrganizationDeleteParams import com.braintrustdata.api.models.OrganizationListPage @@ -12,16 +11,25 @@ import com.braintrustdata.api.models.OrganizationListParams import com.braintrustdata.api.models.OrganizationRetrieveParams import com.braintrustdata.api.models.OrganizationUpdateParams import com.braintrustdata.api.services.blocking.organizations.MemberService +import com.google.errorprone.annotations.MustBeClosed interface OrganizationService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun members(): MemberService /** Get an organization object by its id */ - @JvmOverloads + fun retrieve(params: OrganizationRetrieveParams): Organization = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: OrganizationRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Organization /** @@ -29,26 +37,120 @@ interface OrganizationService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: OrganizationUpdateParams): Organization = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: OrganizationUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Organization /** * List out all organizations. The organizations are sorted by creation date, with the most * recently-created organizations coming first */ - @JvmOverloads + fun list(): OrganizationListPage = list(OrganizationListParams.none()) + + /** @see [list] */ fun list( - params: OrganizationListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: OrganizationListParams = OrganizationListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): OrganizationListPage + /** @see [list] */ + fun list(params: OrganizationListParams = OrganizationListParams.none()): OrganizationListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): OrganizationListPage = + list(OrganizationListParams.none(), requestOptions) + /** Delete an organization object by its id */ - @JvmOverloads + fun delete(params: OrganizationDeleteParams): Organization = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: OrganizationDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Organization + + /** + * A view of [OrganizationService] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + fun members(): MemberService.WithRawResponse + + /** + * Returns a raw HTTP response for `get /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: OrganizationRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: OrganizationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationService.update]. + */ + @MustBeClosed + fun update(params: OrganizationUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/organization`, but is otherwise the same as + * [OrganizationService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(OrganizationListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: OrganizationListParams = OrganizationListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: OrganizationListParams = OrganizationListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(OrganizationListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/organization/{organization_id}`, but is + * otherwise the same as [OrganizationService.delete]. + */ + @MustBeClosed + fun delete(params: OrganizationDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceImpl.kt index 786fc869..b6af330b 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Organization import com.braintrustdata.api.models.OrganizationDeleteParams @@ -16,142 +23,167 @@ import com.braintrustdata.api.models.OrganizationRetrieveParams import com.braintrustdata.api.models.OrganizationUpdateParams import com.braintrustdata.api.services.blocking.organizations.MemberService import com.braintrustdata.api.services.blocking.organizations.MemberServiceImpl -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class OrganizationServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : OrganizationService { +class OrganizationServiceImpl internal constructor(private val clientOptions: ClientOptions) : + OrganizationService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: OrganizationService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } private val members: MemberService by lazy { MemberServiceImpl(clientOptions) } - override fun members(): MemberService = members + override fun withRawResponse(): OrganizationService.WithRawResponse = withRawResponse - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun members(): MemberService = members - /** Get an organization object by its id */ override fun retrieve( params: OrganizationRetrieveParams, - requestOptions: RequestOptions - ): Organization { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): Organization = + // get /v1/organization/{organization_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions, + ): Organization = + // patch /v1/organization/{organization_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: OrganizationListParams, + requestOptions: RequestOptions, + ): OrganizationListPage = + // get /v1/organization + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions, + ): Organization = + // delete /v1/organization/{organization_id} + withRawResponse().delete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + OrganizationService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val members: MemberService.WithRawResponse by lazy { + MemberServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun members(): MemberService.WithRawResponse = members + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: OrganizationRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** - * Partially update an organization object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update( - params: OrganizationUpdateParams, - requestOptions: RequestOptions - ): Organization { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun update( + params: OrganizationUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all organizations. The organizations are sorted by creation date, with the most - * recently-created organizations coming first - */ - override fun list( - params: OrganizationListParams, - requestOptions: RequestOptions - ): OrganizationListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "organization") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: OrganizationListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "organization") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + OrganizationListPage.of(OrganizationServiceImpl(clientOptions), params, it) } - } - .let { OrganizationListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - /** Delete an organization object by its id */ - override fun delete( - params: OrganizationDeleteParams, - requestOptions: RequestOptions - ): Organization { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "organization", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun delete( + params: OrganizationDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "organization", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreService.kt index d440a9a6..5f9df9bc 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ProjectScore import com.braintrustdata.api.models.ProjectScoreCreateParams import com.braintrustdata.api.models.ProjectScoreDeleteParams @@ -13,25 +12,37 @@ import com.braintrustdata.api.models.ProjectScoreListParams import com.braintrustdata.api.models.ProjectScoreReplaceParams import com.braintrustdata.api.models.ProjectScoreRetrieveParams import com.braintrustdata.api.models.ProjectScoreUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface ProjectScoreService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new project_score. If there is an existing project_score in the project with the * same name as the one specified in the request, will return the existing project_score * unmodified */ - @JvmOverloads + fun create(params: ProjectScoreCreateParams): ProjectScore = + create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectScoreCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScore /** Get a project_score object by its id */ - @JvmOverloads + fun retrieve(params: ProjectScoreRetrieveParams): ProjectScore = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectScoreRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScore /** @@ -39,27 +50,43 @@ interface ProjectScoreService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectScoreUpdateParams): ProjectScore = + update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectScoreUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScore /** * List out all project_scores. The project_scores are sorted by creation date, with the most * recently-created project_scores coming first */ - @JvmOverloads + fun list(): ProjectScoreListPage = list(ProjectScoreListParams.none()) + + /** @see [list] */ fun list( - params: ProjectScoreListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectScoreListParams = ProjectScoreListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScoreListPage + /** @see [list] */ + fun list(params: ProjectScoreListParams = ProjectScoreListParams.none()): ProjectScoreListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): ProjectScoreListPage = + list(ProjectScoreListParams.none(), requestOptions) + /** Delete a project_score object by its id */ - @JvmOverloads + fun delete(params: ProjectScoreDeleteParams): ProjectScore = + delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectScoreDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScore /** @@ -67,9 +94,118 @@ interface ProjectScoreService { * the same name as the one specified in the request, will replace the existing project_score * with the provided fields */ - @JvmOverloads + fun replace(params: ProjectScoreReplaceParams): ProjectScore = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ProjectScoreReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectScore + + /** + * A view of [ProjectScoreService] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_score`, but is otherwise the same as + * [ProjectScoreService.create]. + */ + @MustBeClosed + fun create(params: ProjectScoreCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectScoreCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ProjectScoreRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectScoreRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreService.update]. + */ + @MustBeClosed + fun update(params: ProjectScoreUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectScoreUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project_score`, but is otherwise the same as + * [ProjectScoreService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(ProjectScoreListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectScoreListParams = ProjectScoreListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectScoreListParams = ProjectScoreListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(ProjectScoreListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project_score/{project_score_id}`, but is + * otherwise the same as [ProjectScoreService.delete]. + */ + @MustBeClosed + fun delete(params: ProjectScoreDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/project_score`, but is otherwise the same as + * [ProjectScoreService.replace]. + */ + @MustBeClosed + fun replace(params: ProjectScoreReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceImpl.kt index 8adb60b6..ec7b0393 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ProjectScore import com.braintrustdata.api.models.ProjectScoreCreateParams @@ -16,204 +23,225 @@ import com.braintrustdata.api.models.ProjectScoreListParams import com.braintrustdata.api.models.ProjectScoreReplaceParams import com.braintrustdata.api.models.ProjectScoreRetrieveParams import com.braintrustdata.api.models.ProjectScoreUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class ProjectScoreServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectScoreService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new project_score. If there is an existing project_score in the project with the - * same name as the one specified in the request, will return the existing project_score - * unmodified - */ - override fun create( - params: ProjectScoreCreateParams, - requestOptions: RequestOptions - ): ProjectScore { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } + +class ProjectScoreServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectScoreService { + + private val withRawResponse: ProjectScoreService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ProjectScoreService.WithRawResponse = withRawResponse + + override fun create( + params: ProjectScoreCreateParams, + requestOptions: RequestOptions, + ): ProjectScore = + // post /v1/project_score + withRawResponse().create(params, requestOptions).parse() - /** Get a project_score object by its id */ override fun retrieve( params: ProjectScoreRetrieveParams, - requestOptions: RequestOptions - ): ProjectScore { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } - - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + requestOptions: RequestOptions, + ): ProjectScore = + // get /v1/project_score/{project_score_id} + withRawResponse().retrieve(params, requestOptions).parse() - /** - * Partially update a project_score object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ override fun update( params: ProjectScoreUpdateParams, - requestOptions: RequestOptions - ): ProjectScore { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } - - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + requestOptions: RequestOptions, + ): ProjectScore = + // patch /v1/project_score/{project_score_id} + withRawResponse().update(params, requestOptions).parse() - /** - * List out all project_scores. The project_scores are sorted by creation date, with the most - * recently-created project_scores coming first - */ override fun list( params: ProjectScoreListParams, - requestOptions: RequestOptions - ): ProjectScoreListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): ProjectScoreListPage = + // get /v1/project_score + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions, + ): ProjectScore = + // delete /v1/project_score/{project_score_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions, + ): ProjectScore = + // put /v1/project_score + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectScoreService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectScoreCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_score") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ProjectScoreListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ProjectScoreRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } - /** Delete a project_score object by its id */ - override fun delete( - params: ProjectScoreDeleteParams, - requestOptions: RequestOptions - ): ProjectScore { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project_score", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: ProjectScoreUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ProjectScoreListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_score") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + ProjectScoreListPage.of(ProjectScoreServiceImpl(clientOptions), params, it) + } + } + } - /** - * Create or replace project_score. If there is an existing project_score in the project with - * the same name as the one specified in the request, will replace the existing project_score - * with the provided fields - */ - override fun replace( - params: ProjectScoreReplaceParams, - requestOptions: RequestOptions - ): ProjectScore { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "project_score") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ProjectScoreDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project_score", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: ProjectScoreReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "project_score") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectService.kt index 3c46992f..197931d5 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Project import com.braintrustdata.api.models.ProjectCreateParams import com.braintrustdata.api.models.ProjectDeleteParams @@ -13,26 +12,36 @@ import com.braintrustdata.api.models.ProjectListParams import com.braintrustdata.api.models.ProjectRetrieveParams import com.braintrustdata.api.models.ProjectUpdateParams import com.braintrustdata.api.services.blocking.projects.LogService +import com.google.errorprone.annotations.MustBeClosed interface ProjectService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + fun logs(): LogService /** * Create a new project. If there is an existing project with the same name as the one specified * in the request, will return the existing project unmodified */ - @JvmOverloads + fun create(params: ProjectCreateParams): Project = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Project /** Get a project object by its id */ - @JvmOverloads + fun retrieve(params: ProjectRetrieveParams): Project = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Project /** @@ -40,26 +49,130 @@ interface ProjectService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectUpdateParams): Project = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Project /** * List out all projects. The projects are sorted by creation date, with the most * recently-created projects coming first */ - @JvmOverloads + fun list(): ProjectListPage = list(ProjectListParams.none()) + + /** @see [list] */ fun list( - params: ProjectListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectListParams = ProjectListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectListPage + /** @see [list] */ + fun list(params: ProjectListParams = ProjectListParams.none()): ProjectListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): ProjectListPage = + list(ProjectListParams.none(), requestOptions) + /** Delete a project object by its id */ - @JvmOverloads + fun delete(params: ProjectDeleteParams): Project = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Project + + /** A view of [ProjectService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + fun logs(): LogService.WithRawResponse + + /** + * Returns a raw HTTP response for `post /v1/project`, but is otherwise the same as + * [ProjectService.create]. + */ + @MustBeClosed + fun create(params: ProjectCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project/{project_id}`, but is otherwise the same + * as [ProjectService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ProjectRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/project/{project_id}`, but is otherwise the + * same as [ProjectService.update]. + */ + @MustBeClosed + fun update(params: ProjectUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project`, but is otherwise the same as + * [ProjectService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(ProjectListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectListParams = ProjectListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectListParams = ProjectListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(ProjectListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project/{project_id}`, but is otherwise the + * same as [ProjectService.delete]. + */ + @MustBeClosed + fun delete(params: ProjectDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceImpl.kt index 9a166368..502035c3 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Project import com.braintrustdata.api.models.ProjectCreateParams @@ -17,159 +24,184 @@ import com.braintrustdata.api.models.ProjectRetrieveParams import com.braintrustdata.api.models.ProjectUpdateParams import com.braintrustdata.api.services.blocking.projects.LogService import com.braintrustdata.api.services.blocking.projects.LogServiceImpl -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class ProjectServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectService { +class ProjectServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ProjectService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } private val logs: LogService by lazy { LogServiceImpl(clientOptions) } + override fun withRawResponse(): ProjectService.WithRawResponse = withRawResponse + override fun logs(): LogService = logs - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new project. If there is an existing project with the same name as the one specified - * in the request, will return the existing project unmodified - */ - override fun create(params: ProjectCreateParams, requestOptions: RequestOptions): Project { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun create(params: ProjectCreateParams, requestOptions: RequestOptions): Project = + // post /v1/project + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: ProjectRetrieveParams, requestOptions: RequestOptions): Project = + // get /v1/project/{project_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: ProjectUpdateParams, requestOptions: RequestOptions): Project = + // patch /v1/project/{project_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: ProjectListParams, requestOptions: RequestOptions): ProjectListPage = + // get /v1/project + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: ProjectDeleteParams, requestOptions: RequestOptions): Project = + // delete /v1/project/{project_id} + withRawResponse().delete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val logs: LogService.WithRawResponse by lazy { + LogServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun logs(): LogService.WithRawResponse = logs + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a project object by its id */ - override fun retrieve(params: ProjectRetrieveParams, requestOptions: RequestOptions): Project { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ProjectRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a project object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: ProjectUpdateParams, requestOptions: RequestOptions): Project { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: ProjectUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * List out all projects. The projects are sorted by creation date, with the most - * recently-created projects coming first - */ - override fun list(params: ProjectListParams, requestOptions: RequestOptions): ProjectListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ProjectListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ProjectListPage.of(this, params, it) } + .let { ProjectListPage.of(ProjectServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a project object by its id */ - override fun delete(params: ProjectDeleteParams, requestOptions: RequestOptions): Project { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ProjectDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagService.kt index e240afdc..d06930e4 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.ProjectTag import com.braintrustdata.api.models.ProjectTagCreateParams import com.braintrustdata.api.models.ProjectTagDeleteParams @@ -13,24 +12,35 @@ import com.braintrustdata.api.models.ProjectTagListParams import com.braintrustdata.api.models.ProjectTagReplaceParams import com.braintrustdata.api.models.ProjectTagRetrieveParams import com.braintrustdata.api.models.ProjectTagUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface ProjectTagService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new project_tag. If there is an existing project_tag in the project with the same * name as the one specified in the request, will return the existing project_tag unmodified */ - @JvmOverloads + fun create(params: ProjectTagCreateParams): ProjectTag = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ProjectTagCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTag /** Get a project_tag object by its id */ - @JvmOverloads + fun retrieve(params: ProjectTagRetrieveParams): ProjectTag = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ProjectTagRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTag /** @@ -38,27 +48,41 @@ interface ProjectTagService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: ProjectTagUpdateParams): ProjectTag = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ProjectTagUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTag /** * List out all project_tags. The project_tags are sorted by creation date, with the most * recently-created project_tags coming first */ - @JvmOverloads + fun list(): ProjectTagListPage = list(ProjectTagListParams.none()) + + /** @see [list] */ fun list( - params: ProjectTagListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: ProjectTagListParams = ProjectTagListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTagListPage + /** @see [list] */ + fun list(params: ProjectTagListParams = ProjectTagListParams.none()): ProjectTagListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): ProjectTagListPage = + list(ProjectTagListParams.none(), requestOptions) + /** Delete a project_tag object by its id */ - @JvmOverloads + fun delete(params: ProjectTagDeleteParams): ProjectTag = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ProjectTagDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTag /** @@ -66,9 +90,116 @@ interface ProjectTagService { * same name as the one specified in the request, will replace the existing project_tag with the * provided fields */ - @JvmOverloads + fun replace(params: ProjectTagReplaceParams): ProjectTag = + replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ProjectTagReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ProjectTag + + /** A view of [ProjectTagService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_tag`, but is otherwise the same as + * [ProjectTagService.create]. + */ + @MustBeClosed + fun create(params: ProjectTagCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ProjectTagCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project_tag/{project_tag_id}`, but is otherwise + * the same as [ProjectTagService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ProjectTagRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ProjectTagRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/project_tag/{project_tag_id}`, but is + * otherwise the same as [ProjectTagService.update]. + */ + @MustBeClosed + fun update(params: ProjectTagUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ProjectTagUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project_tag`, but is otherwise the same as + * [ProjectTagService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(ProjectTagListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectTagListParams = ProjectTagListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: ProjectTagListParams = ProjectTagListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(ProjectTagListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/project_tag/{project_tag_id}`, but is + * otherwise the same as [ProjectTagService.delete]. + */ + @MustBeClosed + fun delete(params: ProjectTagDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/project_tag`, but is otherwise the same as + * [ProjectTagService.replace]. + */ + @MustBeClosed + fun replace(params: ProjectTagReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceImpl.kt index 79ec9e72..79f8d590 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.ProjectTag import com.braintrustdata.api.models.ProjectTagCreateParams @@ -16,203 +23,223 @@ import com.braintrustdata.api.models.ProjectTagListParams import com.braintrustdata.api.models.ProjectTagReplaceParams import com.braintrustdata.api.models.ProjectTagRetrieveParams import com.braintrustdata.api.models.ProjectTagUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class ProjectTagServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ProjectTagService { +class ProjectTagServiceImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectTagService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: ProjectTagService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): ProjectTagService.WithRawResponse = withRawResponse - /** - * Create a new project_tag. If there is an existing project_tag in the project with the same - * name as the one specified in the request, will return the existing project_tag unmodified - */ override fun create( params: ProjectTagCreateParams, - requestOptions: RequestOptions - ): ProjectTag { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } + requestOptions: RequestOptions, + ): ProjectTag = + // post /v1/project_tag + withRawResponse().create(params, requestOptions).parse() - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a project_tag object by its id */ override fun retrieve( params: ProjectTagRetrieveParams, - requestOptions: RequestOptions - ): ProjectTag { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } + requestOptions: RequestOptions, + ): ProjectTag = + // get /v1/project_tag/{project_tag_id} + withRawResponse().retrieve(params, requestOptions).parse() - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a project_tag object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ override fun update( params: ProjectTagUpdateParams, - requestOptions: RequestOptions - ): ProjectTag { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() - } - } - } - } + requestOptions: RequestOptions, + ): ProjectTag = + // patch /v1/project_tag/{project_tag_id} + withRawResponse().update(params, requestOptions).parse() - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * List out all project_tags. The project_tags are sorted by creation date, with the most - * recently-created project_tags coming first - */ override fun list( params: ProjectTagListParams, - requestOptions: RequestOptions - ): ProjectTagListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): ProjectTagListPage = + // get /v1/project_tag + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions, + ): ProjectTag = + // delete /v1/project_tag/{project_tag_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions, + ): ProjectTag = + // put /v1/project_tag + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ProjectTagService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ProjectTagCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_tag") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ProjectTagListPage.of(this, params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ProjectTagRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } - /** Delete a project_tag object by its id */ - override fun delete( - params: ProjectTagDeleteParams, - requestOptions: RequestOptions - ): ProjectTag { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "project_tag", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: ProjectTagUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ProjectTagListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_tag") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { ProjectTagListPage.of(ProjectTagServiceImpl(clientOptions), params, it) } + } + } - /** - * Create or replace project_tag. If there is an existing project_tag in the project with the - * same name as the one specified in the request, will replace the existing project_tag with the - * provided fields - */ - override fun replace( - params: ProjectTagReplaceParams, - requestOptions: RequestOptions - ): ProjectTag { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "project_tag") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ProjectTagDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "project_tag", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: ProjectTagReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "project_tag") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptService.kt index 78316068..e3d04a03 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Prompt import com.braintrustdata.api.models.PromptCreateParams import com.braintrustdata.api.models.PromptDeleteParams @@ -13,24 +12,34 @@ import com.braintrustdata.api.models.PromptListParams import com.braintrustdata.api.models.PromptReplaceParams import com.braintrustdata.api.models.PromptRetrieveParams import com.braintrustdata.api.models.PromptUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface PromptService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new prompt. If there is an existing prompt in the project with the same slug as the * one specified in the request, will return the existing prompt unmodified */ - @JvmOverloads + fun create(params: PromptCreateParams): Prompt = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: PromptCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Prompt /** Get a prompt object by its id */ - @JvmOverloads + fun retrieve(params: PromptRetrieveParams): Prompt = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: PromptRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Prompt /** @@ -38,36 +47,155 @@ interface PromptService { * object-type fields will be deep-merged with existing content. Currently we do not support * removing fields or setting them to null. */ - @JvmOverloads + fun update(params: PromptUpdateParams): Prompt = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: PromptUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Prompt /** * List out all prompts. The prompts are sorted by creation date, with the most recently-created * prompts coming first */ - @JvmOverloads + fun list(): PromptListPage = list(PromptListParams.none()) + + /** @see [list] */ fun list( - params: PromptListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: PromptListParams = PromptListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): PromptListPage + /** @see [list] */ + fun list(params: PromptListParams = PromptListParams.none()): PromptListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): PromptListPage = + list(PromptListParams.none(), requestOptions) + /** Delete a prompt object by its id */ - @JvmOverloads + fun delete(params: PromptDeleteParams): Prompt = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: PromptDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Prompt /** * Create or replace prompt. If there is an existing prompt in the project with the same slug as * the one specified in the request, will replace the existing prompt with the provided fields */ - @JvmOverloads + fun replace(params: PromptReplaceParams): Prompt = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: PromptReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Prompt + + /** A view of [PromptService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/prompt`, but is otherwise the same as + * [PromptService.create]. + */ + @MustBeClosed + fun create(params: PromptCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: PromptCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/prompt/{prompt_id}`, but is otherwise the same + * as [PromptService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: PromptRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: PromptRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/prompt/{prompt_id}`, but is otherwise the same + * as [PromptService.update]. + */ + @MustBeClosed + fun update(params: PromptUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: PromptUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/prompt`, but is otherwise the same as + * [PromptService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(PromptListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: PromptListParams = PromptListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: PromptListParams = PromptListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(PromptListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/prompt/{prompt_id}`, but is otherwise the + * same as [PromptService.delete]. + */ + @MustBeClosed + fun delete(params: PromptDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: PromptDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/prompt`, but is otherwise the same as + * [PromptService.replace]. + */ + @MustBeClosed + fun replace(params: PromptReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: PromptReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptServiceImpl.kt index 25e6d6b7..7736249d 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/PromptServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Prompt import com.braintrustdata.api.models.PromptCreateParams @@ -16,184 +23,205 @@ import com.braintrustdata.api.models.PromptListParams import com.braintrustdata.api.models.PromptReplaceParams import com.braintrustdata.api.models.PromptRetrieveParams import com.braintrustdata.api.models.PromptUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class PromptServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : PromptService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new prompt. If there is an existing prompt in the project with the same slug as the - * one specified in the request, will return the existing prompt unmodified - */ - override fun create(params: PromptCreateParams, requestOptions: RequestOptions): Prompt { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + +class PromptServiceImpl internal constructor(private val clientOptions: ClientOptions) : + PromptService { + + private val withRawResponse: PromptService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): PromptService.WithRawResponse = withRawResponse + + override fun create(params: PromptCreateParams, requestOptions: RequestOptions): Prompt = + // post /v1/prompt + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: PromptRetrieveParams, requestOptions: RequestOptions): Prompt = + // get /v1/prompt/{prompt_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: PromptUpdateParams, requestOptions: RequestOptions): Prompt = + // patch /v1/prompt/{prompt_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: PromptListParams, requestOptions: RequestOptions): PromptListPage = + // get /v1/prompt + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: PromptDeleteParams, requestOptions: RequestOptions): Prompt = + // delete /v1/prompt/{prompt_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace(params: PromptReplaceParams, requestOptions: RequestOptions): Prompt = + // put /v1/prompt + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + PromptService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: PromptCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "prompt") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a prompt object by its id */ - override fun retrieve(params: PromptRetrieveParams, requestOptions: RequestOptions): Prompt { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: PromptRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a prompt object. Specify the fields to update in the payload. Any - * object-type fields will be deep-merged with existing content. Currently we do not support - * removing fields or setting them to null. - */ - override fun update(params: PromptUpdateParams, requestOptions: RequestOptions): Prompt { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: PromptUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) - - /** - * List out all prompts. The prompts are sorted by creation date, with the most recently-created - * prompts coming first - */ - override fun list(params: PromptListParams, requestOptions: RequestOptions): PromptListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: PromptListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "prompt") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { PromptListPage.of(this, params, it) } + .let { PromptListPage.of(PromptServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a prompt object by its id */ - override fun delete(params: PromptDeleteParams, requestOptions: RequestOptions): Prompt { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "prompt", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: PromptDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "prompt", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace prompt. If there is an existing prompt in the project with the same slug as - * the one specified in the request, will replace the existing prompt with the provided fields - */ - override fun replace(params: PromptReplaceParams, requestOptions: RequestOptions): Prompt { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "prompt") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: PromptReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "prompt") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleService.kt index 6ae7e700..a913ecca 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.Role import com.braintrustdata.api.models.RoleCreateParams import com.braintrustdata.api.models.RoleDeleteParams @@ -13,24 +12,34 @@ import com.braintrustdata.api.models.RoleListParams import com.braintrustdata.api.models.RoleReplaceParams import com.braintrustdata.api.models.RoleRetrieveParams import com.braintrustdata.api.models.RoleUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface RoleService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new role. If there is an existing role with the same name as the one specified in * the request, will return the existing role unmodified */ - @JvmOverloads + fun create(params: RoleCreateParams): Role = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: RoleCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Role /** Get a role object by its id */ - @JvmOverloads + fun retrieve(params: RoleRetrieveParams): Role = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: RoleRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Role /** @@ -38,36 +47,154 @@ interface RoleService { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: RoleUpdateParams): Role = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: RoleUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Role /** * List out all roles. The roles are sorted by creation date, with the most recently-created * roles coming first */ - @JvmOverloads + fun list(): RoleListPage = list(RoleListParams.none()) + + /** @see [list] */ fun list( - params: RoleListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: RoleListParams = RoleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): RoleListPage + /** @see [list] */ + fun list(params: RoleListParams = RoleListParams.none()): RoleListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): RoleListPage = + list(RoleListParams.none(), requestOptions) + /** Delete a role object by its id */ - @JvmOverloads + fun delete(params: RoleDeleteParams): Role = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: RoleDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Role /** * Create or replace role. If there is an existing role with the same name as the one specified * in the request, will replace the existing role with the provided fields */ - @JvmOverloads + fun replace(params: RoleReplaceParams): Role = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: RoleReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): Role + + /** A view of [RoleService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/role`, but is otherwise the same as + * [RoleService.create]. + */ + @MustBeClosed + fun create(params: RoleCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: RoleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/role/{role_id}`, but is otherwise the same as + * [RoleService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: RoleRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: RoleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/role/{role_id}`, but is otherwise the same as + * [RoleService.update]. + */ + @MustBeClosed + fun update(params: RoleUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: RoleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/role`, but is otherwise the same as + * [RoleService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(RoleListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: RoleListParams = RoleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: RoleListParams = RoleListParams.none()): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(RoleListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/role/{role_id}`, but is otherwise the same as + * [RoleService.delete]. + */ + @MustBeClosed + fun delete(params: RoleDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: RoleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/role`, but is otherwise the same as + * [RoleService.replace]. + */ + @MustBeClosed + fun replace(params: RoleReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: RoleReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleServiceImpl.kt index 5f49a6b3..8c0a69cb 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/RoleServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.Role import com.braintrustdata.api.models.RoleCreateParams @@ -16,183 +23,204 @@ import com.braintrustdata.api.models.RoleListParams import com.braintrustdata.api.models.RoleReplaceParams import com.braintrustdata.api.models.RoleRetrieveParams import com.braintrustdata.api.models.RoleUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class RoleServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : RoleService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new role. If there is an existing role with the same name as the one specified in - * the request, will return the existing role unmodified - */ - override fun create(params: RoleCreateParams, requestOptions: RequestOptions): Role { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + +class RoleServiceImpl internal constructor(private val clientOptions: ClientOptions) : RoleService { + + private val withRawResponse: RoleService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): RoleService.WithRawResponse = withRawResponse + + override fun create(params: RoleCreateParams, requestOptions: RequestOptions): Role = + // post /v1/role + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: RoleRetrieveParams, requestOptions: RequestOptions): Role = + // get /v1/role/{role_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: RoleUpdateParams, requestOptions: RequestOptions): Role = + // patch /v1/role/{role_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: RoleListParams, requestOptions: RequestOptions): RoleListPage = + // get /v1/role + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: RoleDeleteParams, requestOptions: RequestOptions): Role = + // delete /v1/role/{role_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace(params: RoleReplaceParams, requestOptions: RequestOptions): Role = + // put /v1/role + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + RoleService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: RoleCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "role") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a role object by its id */ - override fun retrieve(params: RoleRetrieveParams, requestOptions: RequestOptions): Role { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: RoleRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "role", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a role object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update(params: RoleUpdateParams, requestOptions: RequestOptions): Role { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: RoleUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "role", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * List out all roles. The roles are sorted by creation date, with the most recently-created - * roles coming first - */ - override fun list(params: RoleListParams, requestOptions: RequestOptions): RoleListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: RoleListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "role") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { RoleListPage.of(this, params, it) } + .let { RoleListPage.of(RoleServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a role object by its id */ - override fun delete(params: RoleDeleteParams, requestOptions: RequestOptions): Role { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "role", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .apply { params.getBody().ifPresent { body(json(clientOptions.jsonMapper, it)) } } - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: RoleDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "role", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace role. If there is an existing role with the same name as the one specified - * in the request, will replace the existing role with the provided fields - */ - override fun replace(params: RoleReplaceParams, requestOptions: RequestOptions): Role { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "role") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: RoleReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "role") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeService.kt new file mode 100644 index 00000000..f8630cc6 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeService.kt @@ -0,0 +1,204 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.blocking + +import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.models.SpanIFrame +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeListPage +import com.braintrustdata.api.models.SpanIframeListParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams +import com.google.errorprone.annotations.MustBeClosed + +interface SpanIframeService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Create a new span_iframe. If there is an existing span_iframe with the same name as the one + * specified in the request, will return the existing span_iframe unmodified + */ + fun create(params: SpanIframeCreateParams): SpanIFrame = create(params, RequestOptions.none()) + + /** @see [create] */ + fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIFrame + + /** Get a span_iframe object by its id */ + fun retrieve(params: SpanIframeRetrieveParams): SpanIFrame = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIFrame + + /** + * Partially update a span_iframe object. Specify the fields to update in the payload. Any + * object-type fields will be deep-merged with existing content. Currently we do not support + * removing fields or setting them to null. + */ + fun update(params: SpanIframeUpdateParams): SpanIFrame = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIFrame + + /** + * List out all span_iframes. The span_iframes are sorted by creation date, with the most + * recently-created span_iframes coming first + */ + fun list(): SpanIframeListPage = list(SpanIframeListParams.none()) + + /** @see [list] */ + fun list( + params: SpanIframeListParams = SpanIframeListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIframeListPage + + /** @see [list] */ + fun list(params: SpanIframeListParams = SpanIframeListParams.none()): SpanIframeListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): SpanIframeListPage = + list(SpanIframeListParams.none(), requestOptions) + + /** Delete a span_iframe object by its id */ + fun delete(params: SpanIframeDeleteParams): SpanIFrame = delete(params, RequestOptions.none()) + + /** @see [delete] */ + fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIFrame + + /** + * Create or replace span_iframe. If there is an existing span_iframe with the same name as the + * one specified in the request, will replace the existing span_iframe with the provided fields + */ + fun replace(params: SpanIframeReplaceParams): SpanIFrame = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SpanIFrame + + /** A view of [SpanIframeService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/span_iframe`, but is otherwise the same as + * [SpanIframeService.create]. + */ + @MustBeClosed + fun create(params: SpanIframeCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/span_iframe/{span_iframe_id}`, but is otherwise + * the same as [SpanIframeService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: SpanIframeRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/span_iframe/{span_iframe_id}`, but is + * otherwise the same as [SpanIframeService.update]. + */ + @MustBeClosed + fun update(params: SpanIframeUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/span_iframe`, but is otherwise the same as + * [SpanIframeService.list]. + */ + @MustBeClosed + fun list(): HttpResponseFor = list(SpanIframeListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: SpanIframeListParams = SpanIframeListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list( + params: SpanIframeListParams = SpanIframeListParams.none() + ): HttpResponseFor = list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(SpanIframeListParams.none(), requestOptions) + + /** + * Returns a raw HTTP response for `delete /v1/span_iframe/{span_iframe_id}`, but is + * otherwise the same as [SpanIframeService.delete]. + */ + @MustBeClosed + fun delete(params: SpanIframeDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/span_iframe`, but is otherwise the same as + * [SpanIframeService.replace]. + */ + @MustBeClosed + fun replace(params: SpanIframeReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceImpl.kt new file mode 100644 index 00000000..33029900 --- /dev/null +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceImpl.kt @@ -0,0 +1,245 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.blocking + +import com.braintrustdata.api.core.ClientOptions +import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler +import com.braintrustdata.api.core.http.HttpMethod +import com.braintrustdata.api.core.http.HttpRequest +import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare +import com.braintrustdata.api.errors.BraintrustError +import com.braintrustdata.api.models.SpanIFrame +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeListPage +import com.braintrustdata.api.models.SpanIframeListParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams + +class SpanIframeServiceImpl internal constructor(private val clientOptions: ClientOptions) : + SpanIframeService { + + private val withRawResponse: SpanIframeService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): SpanIframeService.WithRawResponse = withRawResponse + + override fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions, + ): SpanIFrame = + // post /v1/span_iframe + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions, + ): SpanIFrame = + // get /v1/span_iframe/{span_iframe_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions, + ): SpanIFrame = + // patch /v1/span_iframe/{span_iframe_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: SpanIframeListParams, + requestOptions: RequestOptions, + ): SpanIframeListPage = + // get /v1/span_iframe + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions, + ): SpanIFrame = + // delete /v1/span_iframe/{span_iframe_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions, + ): SpanIFrame = + // put /v1/span_iframe + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SpanIframeService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: SpanIframeCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "span_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: SpanIframeRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: SpanIframeUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: SpanIframeListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "span_iframe") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { SpanIframeListPage.of(SpanIframeServiceImpl(clientOptions), params, it) } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: SpanIframeDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "span_iframe", params.getPathParam(0)) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: SpanIframeReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "span_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelService.kt index 5aba74fe..f7d77d83 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelService.kt @@ -1,18 +1,62 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.TopLevelHelloWorldParams +import com.google.errorprone.annotations.MustBeClosed interface TopLevelService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Default endpoint. Simply replies with 'Hello, World!'. Authorization is not required */ - @JvmOverloads + fun helloWorld(): String = helloWorld(TopLevelHelloWorldParams.none()) + + /** @see [helloWorld] */ fun helloWorld( - params: TopLevelHelloWorldParams, - requestOptions: RequestOptions = RequestOptions.none() + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): String + + /** @see [helloWorld] */ + fun helloWorld(params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none()): String = + helloWorld(params, RequestOptions.none()) + + /** @see [helloWorld] */ + fun helloWorld(requestOptions: RequestOptions): String = + helloWorld(TopLevelHelloWorldParams.none(), requestOptions) + + /** A view of [TopLevelService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `get /v1`, but is otherwise the same as + * [TopLevelService.helloWorld]. + */ + @MustBeClosed + fun helloWorld(): HttpResponseFor = helloWorld(TopLevelHelloWorldParams.none()) + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld( + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld( + params: TopLevelHelloWorldParams = TopLevelHelloWorldParams.none() + ): HttpResponseFor = helloWorld(params, RequestOptions.none()) + + /** @see [helloWorld] */ + @MustBeClosed + fun helloWorld(requestOptions: RequestOptions): HttpResponseFor = + helloWorld(TopLevelHelloWorldParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceImpl.kt index 631eac96..2bee0c27 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceImpl.kt @@ -4,40 +4,55 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.stringHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.TopLevelHelloWorldParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.stringHandler -import com.braintrustdata.api.services.withErrorHandler -class TopLevelServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : TopLevelService { +class TopLevelServiceImpl internal constructor(private val clientOptions: ClientOptions) : + TopLevelService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: TopLevelService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val helloWorldHandler: Handler = stringHandler().withErrorHandler(errorHandler) + override fun withRawResponse(): TopLevelService.WithRawResponse = withRawResponse - /** Default endpoint. Simply replies with 'Hello, World!'. Authorization is not required */ override fun helloWorld( params: TopLevelHelloWorldParams, - requestOptions: RequestOptions - ): String { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response.use { helloWorldHandler.handle(it) } + requestOptions: RequestOptions, + ): String = + // get /v1 + withRawResponse().helloWorld(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + TopLevelService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val helloWorldHandler: Handler = + stringHandler().withErrorHandler(errorHandler) + + override fun helloWorld( + params: TopLevelHelloWorldParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { response.use { helloWorldHandler.handle(it) } } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserService.kt index 53e07dcb..8a297070 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserService.kt @@ -1,31 +1,90 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.User import com.braintrustdata.api.models.UserListPage import com.braintrustdata.api.models.UserListParams import com.braintrustdata.api.models.UserRetrieveParams +import com.google.errorprone.annotations.MustBeClosed interface UserService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Get a user object by its id */ - @JvmOverloads + fun retrieve(params: UserRetrieveParams): User = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: UserRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): User /** * List out all users. The users are sorted by creation date, with the most recently-created * users coming first */ - @JvmOverloads + fun list(): UserListPage = list(UserListParams.none()) + + /** @see [list] */ fun list( - params: UserListParams, - requestOptions: RequestOptions = RequestOptions.none() + params: UserListParams = UserListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): UserListPage + + /** @see [list] */ + fun list(params: UserListParams = UserListParams.none()): UserListPage = + list(params, RequestOptions.none()) + + /** @see [list] */ + fun list(requestOptions: RequestOptions): UserListPage = + list(UserListParams.none(), requestOptions) + + /** A view of [UserService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `get /v1/user/{user_id}`, but is otherwise the same as + * [UserService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: UserRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: UserRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/user`, but is otherwise the same as + * [UserService.list]. + */ + @MustBeClosed fun list(): HttpResponseFor = list(UserListParams.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: UserListParams = UserListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [list] */ + @MustBeClosed + fun list(params: UserListParams = UserListParams.none()): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list(requestOptions: RequestOptions): HttpResponseFor = + list(UserListParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserServiceImpl.kt index 28ff5d7a..08e5047d 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/UserServiceImpl.kt @@ -4,76 +4,94 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.User import com.braintrustdata.api.models.UserListPage import com.braintrustdata.api.models.UserListParams import com.braintrustdata.api.models.UserRetrieveParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class UserServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : UserService { +class UserServiceImpl internal constructor(private val clientOptions: ClientOptions) : UserService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: UserService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): UserService.WithRawResponse = withRawResponse + + override fun retrieve(params: UserRetrieveParams, requestOptions: RequestOptions): User = + // get /v1/user/{user_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun list(params: UserListParams, requestOptions: RequestOptions): UserListPage = + // get /v1/user + withRawResponse().list(params, requestOptions).parse() - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + UserService.WithRawResponse { - /** Get a user object by its id */ - override fun retrieve(params: UserRetrieveParams, requestOptions: RequestOptions): User { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "user", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: UserRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "user", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * List out all users. The users are sorted by creation date, with the most recently-created - * users coming first - */ - override fun list(params: UserListParams, requestOptions: RequestOptions): UserListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "user") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun list( + params: UserListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "user") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { UserListPage.of(this, params, it) } + .let { UserListPage.of(UserServiceImpl(clientOptions), params, it) } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewService.kt index d71f5ab5..f997b1b2 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.View import com.braintrustdata.api.models.ViewCreateParams import com.braintrustdata.api.models.ViewDeleteParams @@ -13,24 +12,34 @@ import com.braintrustdata.api.models.ViewListParams import com.braintrustdata.api.models.ViewReplaceParams import com.braintrustdata.api.models.ViewRetrieveParams import com.braintrustdata.api.models.ViewUpdateParams +import com.google.errorprone.annotations.MustBeClosed interface ViewService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** * Create a new view. If there is an existing view with the same name as the one specified in * the request, will return the existing view unmodified */ - @JvmOverloads + fun create(params: ViewCreateParams): View = create(params, RequestOptions.none()) + + /** @see [create] */ fun create( params: ViewCreateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): View /** Get a view object by its id */ - @JvmOverloads + fun retrieve(params: ViewRetrieveParams): View = retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ fun retrieve( params: ViewRetrieveParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): View /** @@ -38,36 +47,138 @@ interface ViewService { * fields will be deep-merged with existing content. Currently we do not support removing fields * or setting them to null. */ - @JvmOverloads + fun update(params: ViewUpdateParams): View = update(params, RequestOptions.none()) + + /** @see [update] */ fun update( params: ViewUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): View /** * List out all views. The views are sorted by creation date, with the most recently-created * views coming first */ - @JvmOverloads + fun list(params: ViewListParams): ViewListPage = list(params, RequestOptions.none()) + + /** @see [list] */ fun list( params: ViewListParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): ViewListPage /** Delete a view object by its id */ - @JvmOverloads + fun delete(params: ViewDeleteParams): View = delete(params, RequestOptions.none()) + + /** @see [delete] */ fun delete( params: ViewDeleteParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): View /** * Create or replace view. If there is an existing view with the same name as the one specified * in the request, will replace the existing view with the provided fields */ - @JvmOverloads + fun replace(params: ViewReplaceParams): View = replace(params, RequestOptions.none()) + + /** @see [replace] */ fun replace( params: ViewReplaceParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): View + + /** A view of [ViewService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/view`, but is otherwise the same as + * [ViewService.create]. + */ + @MustBeClosed + fun create(params: ViewCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see [create] */ + @MustBeClosed + fun create( + params: ViewCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/view/{view_id}`, but is otherwise the same as + * [ViewService.retrieve]. + */ + @MustBeClosed + fun retrieve(params: ViewRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see [retrieve] */ + @MustBeClosed + fun retrieve( + params: ViewRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `patch /v1/view/{view_id}`, but is otherwise the same as + * [ViewService.update]. + */ + @MustBeClosed + fun update(params: ViewUpdateParams): HttpResponseFor = + update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: ViewUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/view`, but is otherwise the same as + * [ViewService.list]. + */ + @MustBeClosed + fun list(params: ViewListParams): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see [list] */ + @MustBeClosed + fun list( + params: ViewListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `delete /v1/view/{view_id}`, but is otherwise the same as + * [ViewService.delete]. + */ + @MustBeClosed + fun delete(params: ViewDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see [delete] */ + @MustBeClosed + fun delete( + params: ViewDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put /v1/view`, but is otherwise the same as + * [ViewService.replace]. + */ + @MustBeClosed + fun replace(params: ViewReplaceParams): HttpResponseFor = + replace(params, RequestOptions.none()) + + /** @see [replace] */ + @MustBeClosed + fun replace( + params: ViewReplaceParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewServiceImpl.kt index f682e6d6..8c11e74f 100755 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/ViewServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.View import com.braintrustdata.api.models.ViewCreateParams @@ -16,183 +23,204 @@ import com.braintrustdata.api.models.ViewListParams import com.braintrustdata.api.models.ViewReplaceParams import com.braintrustdata.api.models.ViewRetrieveParams import com.braintrustdata.api.models.ViewUpdateParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler - -class ViewServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : ViewService { - - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) - - private val createHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create a new view. If there is an existing view with the same name as the one specified in - * the request, will return the existing view unmodified - */ - override fun create(params: ViewCreateParams, requestOptions: RequestOptions): View { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { createHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + +class ViewServiceImpl internal constructor(private val clientOptions: ClientOptions) : ViewService { + + private val withRawResponse: ViewService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): ViewService.WithRawResponse = withRawResponse + + override fun create(params: ViewCreateParams, requestOptions: RequestOptions): View = + // post /v1/view + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve(params: ViewRetrieveParams, requestOptions: RequestOptions): View = + // get /v1/view/{view_id} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update(params: ViewUpdateParams, requestOptions: RequestOptions): View = + // patch /v1/view/{view_id} + withRawResponse().update(params, requestOptions).parse() + + override fun list(params: ViewListParams, requestOptions: RequestOptions): ViewListPage = + // get /v1/view + withRawResponse().list(params, requestOptions).parse() + + override fun delete(params: ViewDeleteParams, requestOptions: RequestOptions): View = + // delete /v1/view/{view_id} + withRawResponse().delete(params, requestOptions).parse() + + override fun replace(params: ViewReplaceParams, requestOptions: RequestOptions): View = + // put /v1/view + withRawResponse().replace(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + ViewService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun create( + params: ViewCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "view") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val retrieveHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Get a view object by its id */ - override fun retrieve(params: ViewRetrieveParams, requestOptions: RequestOptions): View { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { retrieveHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun retrieve( + params: ViewRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "view", params.getPathParam(0)) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Partially update a view object. Specify the fields to update in the payload. Any object-type - * fields will be deep-merged with existing content. Currently we do not support removing fields - * or setting them to null. - */ - override fun update(params: ViewUpdateParams, requestOptions: RequestOptions): View { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun update( + params: ViewUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "view", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val listHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * List out all views. The views are sorted by creation date, with the most recently-created - * views coming first - */ - override fun list(params: ViewListParams, requestOptions: RequestOptions): ViewListPage { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { listHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val listHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun list( + params: ViewListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "view") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } - .let { ViewListPage.of(this, params, it) } + .let { ViewListPage.of(ViewServiceImpl(clientOptions), params, it) } + } } - } - private val deleteHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** Delete a view object by its id */ - override fun delete(params: ViewDeleteParams, requestOptions: RequestOptions): View { - val request = - HttpRequest.builder() - .method(HttpMethod.DELETE) - .addPathSegments("v1", "view", params.getPathParam(0)) - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { deleteHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun delete( + params: ViewDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .addPathSegments("v1", "view", params.getPathParam(0)) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val replaceHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) - - /** - * Create or replace view. If there is an existing view with the same name as the one specified - * in the request, will replace the existing view with the provided fields - */ - override fun replace(params: ViewReplaceParams, requestOptions: RequestOptions): View { - val request = - HttpRequest.builder() - .method(HttpMethod.PUT) - .addPathSegments("v1", "view") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { replaceHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + private val replaceHandler: Handler = + jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + + override fun replace( + params: ViewReplaceParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .addPathSegments("v1", "view") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { replaceHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberService.kt index 6ef76fdf..d6298636 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberService.kt @@ -1,19 +1,67 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking.organizations import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.OrganizationMemberUpdateParams import com.braintrustdata.api.models.PatchOrganizationMembersOutput +import com.google.errorprone.annotations.MustBeClosed interface MemberService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Modify organization membership */ - @JvmOverloads + fun update(): PatchOrganizationMembersOutput = update(OrganizationMemberUpdateParams.none()) + + /** @see [update] */ fun update( - params: OrganizationMemberUpdateParams, - requestOptions: RequestOptions = RequestOptions.none() + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), ): PatchOrganizationMembersOutput + + /** @see [update] */ + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none() + ): PatchOrganizationMembersOutput = update(params, RequestOptions.none()) + + /** @see [update] */ + fun update(requestOptions: RequestOptions): PatchOrganizationMembersOutput = + update(OrganizationMemberUpdateParams.none(), requestOptions) + + /** A view of [MemberService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `patch /v1/organization/members`, but is otherwise the + * same as [MemberService.update]. + */ + @MustBeClosed + fun update(): HttpResponseFor = + update(OrganizationMemberUpdateParams.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see [update] */ + @MustBeClosed + fun update( + params: OrganizationMemberUpdateParams = OrganizationMemberUpdateParams.none() + ): HttpResponseFor = update(params, RequestOptions.none()) + + /** @see [update] */ + @MustBeClosed + fun update( + requestOptions: RequestOptions + ): HttpResponseFor = + update(OrganizationMemberUpdateParams.none(), requestOptions) + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceImpl.kt index 749d7bf8..ffd783ac 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceImpl.kt @@ -4,51 +4,67 @@ package com.braintrustdata.api.services.blocking.organizations import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.OrganizationMemberUpdateParams import com.braintrustdata.api.models.PatchOrganizationMembersOutput -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class MemberServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : MemberService { +class MemberServiceImpl internal constructor(private val clientOptions: ClientOptions) : + MemberService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: MemberService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val updateHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + override fun withRawResponse(): MemberService.WithRawResponse = withRawResponse - /** Modify organization membership */ override fun update( params: OrganizationMemberUpdateParams, - requestOptions: RequestOptions - ): PatchOrganizationMembersOutput { - val request = - HttpRequest.builder() - .method(HttpMethod.PATCH) - .addPathSegments("v1", "organization", "members") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { updateHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): PatchOrganizationMembersOutput = + // patch /v1/organization/members + withRawResponse().update(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + MemberService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun update( + params: OrganizationMemberUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.PATCH) + .addPathSegments("v1", "organization", "members") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogService.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogService.kt index 796bb9e8..3289dca2 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogService.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogService.kt @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. -@file:Suppress("OVERLOADS_INTERFACE") // See https://youtrack.jetbrains.com/issue/KT-36102 - package com.braintrustdata.api.services.blocking.projects import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.http.HttpResponseFor import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchProjectLogsEventsResponse import com.braintrustdata.api.models.InsertEventsResponse @@ -12,40 +11,126 @@ import com.braintrustdata.api.models.ProjectLogFeedbackParams import com.braintrustdata.api.models.ProjectLogFetchParams import com.braintrustdata.api.models.ProjectLogFetchPostParams import com.braintrustdata.api.models.ProjectLogInsertParams +import com.google.errorprone.annotations.MustBeClosed interface LogService { + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + /** Log feedback for a set of project logs events */ - @JvmOverloads + fun feedback(params: ProjectLogFeedbackParams): FeedbackResponseSchema = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ fun feedback( params: ProjectLogFeedbackParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FeedbackResponseSchema /** * Fetch the events in a project logs. Equivalent to the POST form of the same path, but with - * the parameters in the URL query rather than in the request body + * the parameters in the URL query rather than in the request body. For more complex queries, + * use the `POST /btql` endpoint. */ - @JvmOverloads + fun fetch(params: ProjectLogFetchParams): FetchProjectLogsEventsResponse = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ fun fetch( params: ProjectLogFetchParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchProjectLogsEventsResponse /** * Fetch the events in a project logs. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query + * parameters in the request body rather than in the URL query. For more complex queries, use + * the `POST /btql` endpoint. */ - @JvmOverloads + fun fetchPost(params: ProjectLogFetchPostParams): FetchProjectLogsEventsResponse = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ fun fetchPost( params: ProjectLogFetchPostParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): FetchProjectLogsEventsResponse /** Insert a set of events into the project logs */ - @JvmOverloads + fun insert(params: ProjectLogInsertParams): InsertEventsResponse = + insert(params, RequestOptions.none()) + + /** @see [insert] */ fun insert( params: ProjectLogInsertParams, - requestOptions: RequestOptions = RequestOptions.none() + requestOptions: RequestOptions = RequestOptions.none(), ): InsertEventsResponse + + /** A view of [LogService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/feedback`, but is + * otherwise the same as [LogService.feedback]. + */ + @MustBeClosed + fun feedback(params: ProjectLogFeedbackParams): HttpResponseFor = + feedback(params, RequestOptions.none()) + + /** @see [feedback] */ + @MustBeClosed + fun feedback( + params: ProjectLogFeedbackParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get /v1/project_logs/{project_id}/fetch`, but is + * otherwise the same as [LogService.fetch]. + */ + @MustBeClosed + fun fetch(params: ProjectLogFetchParams): HttpResponseFor = + fetch(params, RequestOptions.none()) + + /** @see [fetch] */ + @MustBeClosed + fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/fetch`, but is + * otherwise the same as [LogService.fetchPost]. + */ + @MustBeClosed + fun fetchPost( + params: ProjectLogFetchPostParams + ): HttpResponseFor = + fetchPost(params, RequestOptions.none()) + + /** @see [fetchPost] */ + @MustBeClosed + fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `post /v1/project_logs/{project_id}/insert`, but is + * otherwise the same as [LogService.insert]. + */ + @MustBeClosed + fun insert(params: ProjectLogInsertParams): HttpResponseFor = + insert(params, RequestOptions.none()) + + /** @see [insert] */ + @MustBeClosed + fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } } diff --git a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceImpl.kt b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceImpl.kt index 9f21671a..d060fec8 100644 --- a/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceImpl.kt +++ b/braintrust-java-core/src/main/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceImpl.kt @@ -4,9 +4,16 @@ package com.braintrustdata.api.services.blocking.projects import com.braintrustdata.api.core.ClientOptions import com.braintrustdata.api.core.RequestOptions +import com.braintrustdata.api.core.handlers.errorHandler +import com.braintrustdata.api.core.handlers.jsonHandler +import com.braintrustdata.api.core.handlers.withErrorHandler import com.braintrustdata.api.core.http.HttpMethod import com.braintrustdata.api.core.http.HttpRequest import com.braintrustdata.api.core.http.HttpResponse.Handler +import com.braintrustdata.api.core.http.HttpResponseFor +import com.braintrustdata.api.core.http.json +import com.braintrustdata.api.core.http.parseable +import com.braintrustdata.api.core.prepare import com.braintrustdata.api.errors.BraintrustError import com.braintrustdata.api.models.FeedbackResponseSchema import com.braintrustdata.api.models.FetchProjectLogsEventsResponse @@ -15,138 +22,157 @@ import com.braintrustdata.api.models.ProjectLogFeedbackParams import com.braintrustdata.api.models.ProjectLogFetchParams import com.braintrustdata.api.models.ProjectLogFetchPostParams import com.braintrustdata.api.models.ProjectLogInsertParams -import com.braintrustdata.api.services.errorHandler -import com.braintrustdata.api.services.json -import com.braintrustdata.api.services.jsonHandler -import com.braintrustdata.api.services.withErrorHandler -class LogServiceImpl -constructor( - private val clientOptions: ClientOptions, -) : LogService { +class LogServiceImpl internal constructor(private val clientOptions: ClientOptions) : LogService { - private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + private val withRawResponse: LogService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } - private val feedbackHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + override fun withRawResponse(): LogService.WithRawResponse = withRawResponse - /** Log feedback for a set of project logs events */ override fun feedback( params: ProjectLogFeedbackParams, - requestOptions: RequestOptions - ): FeedbackResponseSchema { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "feedback") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { feedbackHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + requestOptions: RequestOptions, + ): FeedbackResponseSchema = + // post /v1/project_logs/{project_id}/feedback + withRawResponse().feedback(params, requestOptions).parse() + + override fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions, + ): FetchProjectLogsEventsResponse = + // get /v1/project_logs/{project_id}/fetch + withRawResponse().fetch(params, requestOptions).parse() + + override fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions, + ): FetchProjectLogsEventsResponse = + // post /v1/project_logs/{project_id}/fetch + withRawResponse().fetchPost(params, requestOptions).parse() + + override fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions, + ): InsertEventsResponse = + // post /v1/project_logs/{project_id}/insert + withRawResponse().insert(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LogService.WithRawResponse { + + private val errorHandler: Handler = errorHandler(clientOptions.jsonMapper) + + private val feedbackHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) + + override fun feedback( + params: ProjectLogFeedbackParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "feedback") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { feedbackHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a project logs. Equivalent to the POST form of the same path, but with - * the parameters in the URL query rather than in the request body - */ - override fun fetch( - params: ProjectLogFetchParams, - requestOptions: RequestOptions - ): FetchProjectLogsEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.GET) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetch( + params: ProjectLogFetchParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val fetchPostHandler: Handler = - jsonHandler(clientOptions.jsonMapper) - .withErrorHandler(errorHandler) + private val fetchPostHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** - * Fetch the events in a project logs. Equivalent to the GET form of the same path, but with the - * parameters in the request body rather than in the URL query - */ - override fun fetchPost( - params: ProjectLogFetchPostParams, - requestOptions: RequestOptions - ): FetchProjectLogsEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { fetchPostHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun fetchPost( + params: ProjectLogFetchPostParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "fetch") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { fetchPostHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } - } - private val insertHandler: Handler = - jsonHandler(clientOptions.jsonMapper).withErrorHandler(errorHandler) + private val insertHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + .withErrorHandler(errorHandler) - /** Insert a set of events into the project logs */ - override fun insert( - params: ProjectLogInsertParams, - requestOptions: RequestOptions - ): InsertEventsResponse { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegments("v1", "project_logs", params.getPathParam(0), "insert") - .putAllQueryParams(clientOptions.queryParams) - .putAllQueryParams(params.getQueryParams()) - .putAllHeaders(clientOptions.headers) - .putAllHeaders(params.getHeaders()) - .body(json(clientOptions.jsonMapper, params.getBody())) - .build() - return clientOptions.httpClient.execute(request, requestOptions).let { response -> - response - .use { insertHandler.handle(it) } - .apply { - if (requestOptions.responseValidation ?: clientOptions.responseValidation) { - validate() + override fun insert( + params: ProjectLogInsertParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegments("v1", "project_logs", params.getPathParam(0), "insert") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return response.parseable { + response + .use { insertHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } } - } + } } } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/TestServerExtension.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/TestServerExtension.kt index d79a0c57..1d2dd2d0 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/TestServerExtension.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/TestServerExtension.kt @@ -36,7 +36,7 @@ class TestServerExtension : BeforeAllCallback, ExecutionCondition { $ prism mock path/to/your.openapi.yml """ .trimIndent(), - e + e, ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/PhantomReachableTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/PhantomReachableTest.kt new file mode 100644 index 00000000..a7a9b514 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/PhantomReachableTest.kt @@ -0,0 +1,27 @@ +package com.braintrustdata.api.core + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PhantomReachableTest { + + @Test + fun closeWhenPhantomReachable_whenObservedIsGarbageCollected_closesCloseable() { + var closed = false + val closeable = AutoCloseable { closed = true } + + closeWhenPhantomReachable( + // Pass an inline object for the object to observe so that it becomes immediately + // unreachable. + Any(), + closeable, + ) + + assertThat(closed).isFalse() + + System.gc() + Thread.sleep(3000) + + assertThat(closed).isTrue() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/UtilsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/UtilsTest.kt new file mode 100644 index 00000000..43a97498 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/UtilsTest.kt @@ -0,0 +1,33 @@ +package com.braintrustdata.api.core + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class UtilsTest { + @Test + fun contentDeepEquals() { + assertThat(42 contentEquals 42).isTrue() + assertThat(42 contentEquals "Hello World!").isFalse() + assertThat(byteArrayOf(1, 2, 3) contentEquals byteArrayOf(1, 2, 3)).isTrue() + assertThat(byteArrayOf(1, 2, 3) contentEquals byteArrayOf(1, 2, 4)).isFalse() + assertThat( + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) contentEquals + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) + ) + .isTrue() + assertThat( + arrayOf(byteArrayOf(1, 2), byteArrayOf(3)) contentEquals + arrayOf(byteArrayOf(1), byteArrayOf(2, 3)) + ) + .isFalse() + } + + @Test + fun contentToString() { + assertThat((42).contentToString()).isEqualTo("42") + assertThat("Hello World!".contentToString()).isEqualTo("Hello World!") + assertThat(byteArrayOf(1, 2, 3).contentToString()).isEqualTo("[1, 2, 3]") + assertThat(arrayOf(byteArrayOf(1, 2), byteArrayOf(3)).contentToString()) + .isEqualTo("[[1, 2], [3]]") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/ValuesTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/ValuesTest.kt new file mode 100644 index 00000000..fcdb9f5c --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/ValuesTest.kt @@ -0,0 +1,144 @@ +package com.braintrustdata.api.core + +import java.util.Optional +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ValuesTest { + companion object { + private val NON_JSON = Any() + } + + enum class TestCase( + val value: JsonField<*>, + val expectedIsMissing: Boolean = false, + val expectedIsNull: Boolean = false, + val expectedAsKnown: Optional<*> = Optional.empty(), + val expectedAsBoolean: Optional = Optional.empty(), + val expectedAsNumber: Optional = Optional.empty(), + val expectedAsString: Optional = Optional.empty(), + val expectedAsArray: Optional> = Optional.empty(), + val expectedAsObject: Optional> = Optional.empty(), + ) { + MISSING(JsonMissing.of(), expectedIsMissing = true), + NULL(JsonNull.of(), expectedIsNull = true), + KNOWN(KnownValue.of(NON_JSON), expectedAsKnown = Optional.of(NON_JSON)), + KNOWN_BOOLEAN( + KnownValue.of(true), + expectedAsKnown = Optional.of(true), + expectedAsBoolean = Optional.of(true), + ), + BOOLEAN(JsonBoolean.of(true), expectedAsBoolean = Optional.of(true)), + KNOWN_NUMBER( + KnownValue.of(42), + expectedAsKnown = Optional.of(42), + expectedAsNumber = Optional.of(42), + ), + NUMBER(JsonNumber.of(42), expectedAsNumber = Optional.of(42)), + KNOWN_STRING( + KnownValue.of("hello"), + expectedAsKnown = Optional.of("hello"), + expectedAsString = Optional.of("hello"), + ), + STRING(JsonString.of("hello"), expectedAsString = Optional.of("hello")), + KNOWN_ARRAY_NOT_ALL_JSON( + KnownValue.of(listOf("a", "b", NON_JSON)), + expectedAsKnown = Optional.of(listOf("a", "b", NON_JSON)), + ), + KNOWN_ARRAY( + KnownValue.of(listOf("a", "b", "c")), + expectedAsKnown = Optional.of(listOf("a", "b", "c")), + expectedAsArray = + Optional.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + ), + ARRAY( + JsonArray.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + expectedAsArray = + Optional.of(listOf(JsonString.of("a"), JsonString.of("b"), JsonString.of("c"))), + ), + KNOWN_OBJECT_NOT_ALL_STRING_KEYS( + KnownValue.of(mapOf("a" to "b", 42 to "c")), + expectedAsKnown = Optional.of(mapOf("a" to "b", 42 to "c")), + ), + KNOWN_OBJECT_NOT_ALL_JSON( + KnownValue.of(mapOf("a" to "b", "b" to NON_JSON)), + expectedAsKnown = Optional.of(mapOf("a" to "b", "b" to NON_JSON)), + ), + KNOWN_OBJECT( + KnownValue.of(mapOf("a" to "b", "b" to "c")), + expectedAsKnown = Optional.of(mapOf("a" to "b", "b" to "c")), + expectedAsObject = + Optional.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + ), + OBJECT( + JsonObject.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + expectedAsObject = + Optional.of(mapOf("a" to JsonString.of("b"), "b" to JsonString.of("c"))), + ), + } + + @ParameterizedTest + @EnumSource + fun isMissing(testCase: TestCase) { + val isMissing = testCase.value.isMissing() + + assertThat(isMissing).isEqualTo(testCase.expectedIsMissing) + } + + @ParameterizedTest + @EnumSource + fun isNull(testCase: TestCase) { + val isNull = testCase.value.isNull() + + assertThat(isNull).isEqualTo(testCase.expectedIsNull) + } + + @ParameterizedTest + @EnumSource + fun asKnown(testCase: TestCase) { + val known = testCase.value.asKnown() + + assertThat(known).isEqualTo(testCase.expectedAsKnown) + } + + @ParameterizedTest + @EnumSource + fun asBoolean(testCase: TestCase) { + val boolean = testCase.value.asBoolean() + + assertThat(boolean).isEqualTo(testCase.expectedAsBoolean) + } + + @ParameterizedTest + @EnumSource + fun asNumber(testCase: TestCase) { + val number = testCase.value.asNumber() + + assertThat(number).isEqualTo(testCase.expectedAsNumber) + } + + @ParameterizedTest + @EnumSource + fun asString(testCase: TestCase) { + val string = testCase.value.asString() + + assertThat(string).isEqualTo(testCase.expectedAsString) + } + + @ParameterizedTest + @EnumSource + fun asArray(testCase: TestCase) { + val array = testCase.value.asArray() + + assertThat(array).isEqualTo(testCase.expectedAsArray) + } + + @ParameterizedTest + @EnumSource + fun asObject(testCase: TestCase) { + val obj = testCase.value.asObject() + + assertThat(obj).isEqualTo(testCase.expectedAsObject) + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HeadersTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HeadersTest.kt new file mode 100644 index 00000000..2a5ed57a --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HeadersTest.kt @@ -0,0 +1,274 @@ +package com.braintrustdata.api.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.assertj.core.api.Assumptions.assumeThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class HeadersTest { + + enum class TestCase( + val headers: Headers, + val expectedMap: Map>, + val expectedSize: Int, + ) { + EMPTY(Headers.builder().build(), expectedMap = mapOf(), expectedSize = 0), + PUT_ONE( + Headers.builder().put("name", "value").build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + PUT_MULTIPLE( + Headers.builder().put("name", listOf("value1", "value2")).build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT( + Headers.builder().put("name1", "value").put("name2", "value").build(), + expectedMap = mapOf("name1" to listOf("value"), "name2" to listOf("value")), + expectedSize = 2, + ), + MULTIPLE_PUT_SAME_NAME( + Headers.builder().put("name", "value1").put("name", "value2").build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .put("name", listOf("value1", "value2")) + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value1", "value2")), + expectedSize = 4, + ), + PUT_CASE_INSENSITIVE( + Headers.builder() + .put("name", "value1") + .put("NAME", "value2") + .put("nAmE", "value3") + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value3")), + expectedSize = 3, + ), + PUT_ALL_MAP( + Headers.builder() + .putAll( + mapOf( + "name1" to listOf("value1", "value2"), + "name2" to listOf("value1", "value2"), + ) + ) + .build(), + expectedMap = + mapOf("name1" to listOf("value1", "value2"), "name2" to listOf("value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_HEADERS( + Headers.builder().putAll(Headers.builder().put("name", "value").build()).build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + PUT_ALL_CASE_INSENSITIVE( + Headers.builder() + .putAll( + mapOf( + "name" to listOf("value1"), + "NAME" to listOf("value2"), + "nAmE" to listOf("value3"), + ) + ) + .build(), + expectedMap = mapOf("name" to listOf("value1", "value2", "value3")), + expectedSize = 3, + ), + REMOVE_ABSENT( + Headers.builder().remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_ONE( + Headers.builder().put("name", "value").remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_MULTIPLE( + Headers.builder().put("name", listOf("value1", "value2")).remove("name").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_CASE_INSENSITIVE( + Headers.builder().put("name", listOf("value1", "value2")).remove("NAME").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL( + Headers.builder() + .put("name1", "value") + .put("name3", "value") + .removeAll(setOf("name1", "name2", "name3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL_CASE_INSENSITIVE( + Headers.builder() + .put("name1", "value") + .put("name3", "value") + .removeAll(setOf("NAME1", "nAmE3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + CLEAR( + Headers.builder().put("name1", "value").put("name2", "value").clear().build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REPLACE_ONE_ABSENT( + Headers.builder().replace("name", "value").build(), + expectedMap = mapOf("name" to listOf("value")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_ONE( + Headers.builder().put("name", "value1").replace("name", "value2").build(), + expectedMap = mapOf("name" to listOf("value2")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .replace("name", "value3") + .build(), + expectedMap = mapOf("name" to listOf("value3")), + expectedSize = 1, + ), + REPLACE_MULTIPLE_ABSENT( + Headers.builder().replace("name", listOf("value1", "value2")).build(), + expectedMap = mapOf("name" to listOf("value1", "value2")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_ONE( + Headers.builder() + .put("name", "value1") + .replace("name", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("name" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_MULTIPLE( + Headers.builder() + .put("name", listOf("value1", "value2")) + .replace("name", listOf("value3", "value4")) + .build(), + expectedMap = mapOf("name" to listOf("value3", "value4")), + expectedSize = 2, + ), + REPLACE_CASE_INSENSITIVE( + Headers.builder() + .put("name", "value1") + .replace("NAME", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("NAME" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_ALL_MAP( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .put("name3", "value1") + .replaceAll(mapOf("name1" to listOf("value2"), "name3" to listOf("value2"))) + .build(), + expectedMap = + mapOf( + "name1" to listOf("value2"), + "name2" to listOf("value1"), + "name3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_HEADERS( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .put("name3", "value1") + .replaceAll(Headers.builder().put("name1", "value2").put("name3", "value2").build()) + .build(), + expectedMap = + mapOf( + "name1" to listOf("value2"), + "name2" to listOf("value1"), + "name3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_CASE_INSENSITIVE( + Headers.builder() + .put("name1", "value1") + .put("name2", "value1") + .replaceAll(mapOf("NAME1" to listOf("value2"), "nAmE2" to listOf("value2"))) + .build(), + expectedMap = mapOf("NAME1" to listOf("value2"), "nAmE2" to listOf("value2")), + expectedSize = 2, + ), + } + + @ParameterizedTest + @EnumSource + fun namesAndValues(testCase: TestCase) { + val map = mutableMapOf>() + val headers = testCase.headers + headers.names().forEach { name -> map[name] = headers.values(name) } + + assertThat(map).isEqualTo(testCase.expectedMap) + } + + @ParameterizedTest + @EnumSource + fun caseInsensitiveNames(testCase: TestCase) { + val headers = testCase.headers + + for (name in headers.names()) { + assertThat(headers.values(name)).isEqualTo(headers.values(name.lowercase())) + assertThat(headers.values(name)).isEqualTo(headers.values(name.uppercase())) + } + } + + @ParameterizedTest + @EnumSource + fun size(testCase: TestCase) { + val size = testCase.headers.size + + assertThat(size).isEqualTo(testCase.expectedSize) + } + + @ParameterizedTest + @EnumSource + fun namesAreImmutable(testCase: TestCase) { + val headers = testCase.headers + val headerNamesCopy = headers.names().toSet() + + val throwable = catchThrowable { + (headers.names() as MutableSet).add("another name") + } + + assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java) + assertThat(headers.names()).isEqualTo(headerNamesCopy) + } + + @ParameterizedTest + @EnumSource + fun valuesAreImmutable(testCase: TestCase) { + val headers = testCase.headers + assumeThat(headers.size).isNotEqualTo(0) + val name = headers.names().first() + val headerValuesCopy = headers.values(name).toList() + + val throwable = catchThrowable { + (headers.values(name) as MutableList).add("another value") + } + + assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java) + assertThat(headers.values(name)).isEqualTo(headerValuesCopy) + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HttpRequestTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HttpRequestTest.kt deleted file mode 100755 index 8c937928..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/HttpRequestTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.braintrustdata.api.core.http - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class HttpRequestTest { - - @Test - fun caseInsensitiveHeadersAccessors() { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .putHeader("something_lowercase", "lowercase") - .putHeader("Something_Capitalized", "Capitalized") - .putHeader("SOMETHING_UPPERCASE", "UPPERCASE") - .build() - assertThat(request.headers.get("SOMETHING_LOWERCASE").getOrNull(0)).isEqualTo("lowercase") - assertThat(request.headers.get("something_capitalized").getOrNull(0)) - .isEqualTo("Capitalized") - assertThat(request.headers.get("Something_Uppercase").getOrNull(0)).isEqualTo("UPPERCASE") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/QueryParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/QueryParamsTest.kt new file mode 100644 index 00000000..08e55c66 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/QueryParamsTest.kt @@ -0,0 +1,212 @@ +package com.braintrustdata.api.core.http + +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.catchThrowable +import org.assertj.core.api.Assumptions.assumeThat +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class QueryParamsTest { + + enum class TestCase( + val queryParams: QueryParams, + val expectedMap: Map>, + val expectedSize: Int, + ) { + EMPTY(QueryParams.builder().build(), expectedMap = mapOf(), expectedSize = 0), + PUT_ONE( + QueryParams.builder().put("key", "value").build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + PUT_MULTIPLE( + QueryParams.builder().put("key", listOf("value1", "value2")).build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT( + QueryParams.builder().put("key1", "value").put("key2", "value").build(), + expectedMap = mapOf("key1" to listOf("value"), "key2" to listOf("value")), + expectedSize = 2, + ), + MULTIPLE_PUT_SAME_NAME( + QueryParams.builder().put("key", "value1").put("key", "value2").build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + MULTIPLE_PUT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .put("key", listOf("value1", "value2")) + .build(), + expectedMap = mapOf("key" to listOf("value1", "value2", "value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_MAP( + QueryParams.builder() + .putAll( + mapOf( + "key1" to listOf("value1", "value2"), + "key2" to listOf("value1", "value2"), + ) + ) + .build(), + expectedMap = + mapOf("key1" to listOf("value1", "value2"), "key2" to listOf("value1", "value2")), + expectedSize = 4, + ), + PUT_ALL_HEADERS( + QueryParams.builder().putAll(QueryParams.builder().put("key", "value").build()).build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + REMOVE_ABSENT( + QueryParams.builder().remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_ONE( + QueryParams.builder().put("key", "value").remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_PRESENT_MULTIPLE( + QueryParams.builder().put("key", listOf("value1", "value2")).remove("key").build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REMOVE_ALL( + QueryParams.builder() + .put("key1", "value") + .put("key3", "value") + .removeAll(setOf("key1", "key2", "key3")) + .build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + CLEAR( + QueryParams.builder().put("key1", "value").put("key2", "value").clear().build(), + expectedMap = mapOf(), + expectedSize = 0, + ), + REPLACE_ONE_ABSENT( + QueryParams.builder().replace("key", "value").build(), + expectedMap = mapOf("key" to listOf("value")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_ONE( + QueryParams.builder().put("key", "value1").replace("key", "value2").build(), + expectedMap = mapOf("key" to listOf("value2")), + expectedSize = 1, + ), + REPLACE_ONE_PRESENT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .replace("key", "value3") + .build(), + expectedMap = mapOf("key" to listOf("value3")), + expectedSize = 1, + ), + REPLACE_MULTIPLE_ABSENT( + QueryParams.builder().replace("key", listOf("value1", "value2")).build(), + expectedMap = mapOf("key" to listOf("value1", "value2")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_ONE( + QueryParams.builder() + .put("key", "value1") + .replace("key", listOf("value2", "value3")) + .build(), + expectedMap = mapOf("key" to listOf("value2", "value3")), + expectedSize = 2, + ), + REPLACE_MULTIPLE_PRESENT_MULTIPLE( + QueryParams.builder() + .put("key", listOf("value1", "value2")) + .replace("key", listOf("value3", "value4")) + .build(), + expectedMap = mapOf("key" to listOf("value3", "value4")), + expectedSize = 2, + ), + REPLACE_ALL_MAP( + QueryParams.builder() + .put("key1", "value1") + .put("key2", "value1") + .put("key3", "value1") + .replaceAll(mapOf("key1" to listOf("value2"), "key3" to listOf("value2"))) + .build(), + expectedMap = + mapOf( + "key1" to listOf("value2"), + "key2" to listOf("value1"), + "key3" to listOf("value2"), + ), + expectedSize = 3, + ), + REPLACE_ALL_HEADERS( + QueryParams.builder() + .put("key1", "value1") + .put("key2", "value1") + .put("key3", "value1") + .replaceAll( + QueryParams.builder().put("key1", "value2").put("key3", "value2").build() + ) + .build(), + expectedMap = + mapOf( + "key1" to listOf("value2"), + "key2" to listOf("value1"), + "key3" to listOf("value2"), + ), + expectedSize = 3, + ), + } + + @ParameterizedTest + @EnumSource + fun keysAndValues(testCase: TestCase) { + val map = mutableMapOf>() + val queryParams = testCase.queryParams + queryParams.keys().forEach { key -> map[key] = queryParams.values(key) } + + assertThat(map).isEqualTo(testCase.expectedMap) + } + + @ParameterizedTest + @EnumSource + fun size(testCase: TestCase) { + val size = testCase.queryParams.size + + assertThat(size).isEqualTo(testCase.expectedSize) + } + + @ParameterizedTest + @EnumSource + fun keysAreImmutable(testCase: TestCase) { + val queryParams = testCase.queryParams + val queryParamKeysCopy = queryParams.keys().toSet() + + val throwable = catchThrowable { + (queryParams.keys() as MutableSet).add("another key") + } + + assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java) + assertThat(queryParams.keys()).isEqualTo(queryParamKeysCopy) + } + + @ParameterizedTest + @EnumSource + fun valuesAreImmutable(testCase: TestCase) { + val queryParams = testCase.queryParams + assumeThat(queryParams.size).isNotEqualTo(0) + val key = queryParams.keys().first() + val queryParamValuesCopy = queryParams.values(key).toList() + + val throwable = catchThrowable { + (queryParams.values(key) as MutableList).add("another value") + } + + assertThat(throwable).isInstanceOf(UnsupportedOperationException::class.java) + assertThat(queryParams.values(key)).isEqualTo(queryParamValuesCopy) + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/RetryingHttpClientTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/RetryingHttpClientTest.kt index 2ab73012..d538b9b3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/RetryingHttpClientTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/RetryingHttpClientTest.kt @@ -1,42 +1,87 @@ package com.braintrustdata.api.core.http import com.braintrustdata.api.client.okhttp.OkHttpClient +import com.braintrustdata.api.core.RequestOptions import com.github.tomakehurst.wiremock.client.WireMock.* import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.github.tomakehurst.wiremock.stubbing.Scenario +import java.io.InputStream +import java.util.concurrent.CompletableFuture import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource @WireMockTest internal class RetryingHttpClientTest { + private var openResponseCount = 0 private lateinit var httpClient: HttpClient @BeforeEach fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { - httpClient = OkHttpClient.builder().baseUrl(wmRuntimeInfo.httpBaseUrl).build() + val okHttpClient = OkHttpClient.builder().baseUrl(wmRuntimeInfo.httpBaseUrl).build() + httpClient = + object : HttpClient { + override fun execute( + request: HttpRequest, + requestOptions: RequestOptions, + ): HttpResponse = trackClose(okHttpClient.execute(request, requestOptions)) + + override fun executeAsync( + request: HttpRequest, + requestOptions: RequestOptions, + ): CompletableFuture = + okHttpClient.executeAsync(request, requestOptions).thenApply { trackClose(it) } + + override fun close() = okHttpClient.close() + + private fun trackClose(response: HttpResponse): HttpResponse { + openResponseCount++ + return object : HttpResponse { + private var isClosed = false + + override fun statusCode(): Int = response.statusCode() + + override fun headers(): Headers = response.headers() + + override fun body(): InputStream = response.body() + + override fun close() { + response.close() + if (isClosed) { + return + } + openResponseCount-- + isClosed = true + } + } + } + } resetAllScenarios() } - @Test - fun byDefaultShouldNotAddIdempotencyHeaderToRequest() { - val request = - HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build() + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute(async: Boolean) { stubFor(post(urlPathEqualTo("/something")).willReturn(ok())) val retryingClient = RetryingHttpClient.builder().httpClient(httpClient).build() - val response = retryingClient.execute(request) + + val response = + retryingClient.execute( + HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build(), + async, + ) + assertThat(response.statusCode()).isEqualTo(200) verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() } - @Test - fun whenProvidedShouldAddIdempotencyHeaderToRequest() { - val request = - HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build() + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withIdempotencyHeader(async: Boolean) { stubFor( post(urlPathEqualTo("/something")) .withHeader("X-Some-Header", matching("stainless-java-retry-.+")) @@ -45,21 +90,28 @@ internal class RetryingHttpClientTest { val retryingClient = RetryingHttpClient.builder() .httpClient(httpClient) + .maxRetries(2) .idempotencyHeader("X-Some-Header") .build() - val response = retryingClient.execute(request) + + val response = + retryingClient.execute( + HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build(), + async, + ) + assertThat(response.statusCode()).isEqualTo(200) verify(1, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() } @ParameterizedTest @ValueSource(booleans = [false, true]) - fun retryAfterHeader(async: Boolean) { - val request = - HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build() + fun execute_withRetryAfterHeader(async: Boolean) { stubFor( post(urlPathEqualTo("/something")) - .inScenario("foo") // first we fail with a retry after header given as a date + // First we fail with a retry after header given as a date + .inScenario("foo") .whenScenarioStateIs(Scenario.STARTED) .willReturn( serviceUnavailable().withHeader("Retry-After", "Wed, 21 Oct 2015 07:28:00 GMT") @@ -68,14 +120,16 @@ internal class RetryingHttpClientTest { ) stubFor( post(urlPathEqualTo("/something")) - .inScenario("foo") // then we fail with a retry after header given as a delay + // Then we fail with a retry after header given as a delay + .inScenario("foo") .whenScenarioStateIs("RETRY_AFTER_DATE") .willReturn(serviceUnavailable().withHeader("Retry-After", "1.234")) .willSetStateTo("RETRY_AFTER_DELAY") ) stubFor( post(urlPathEqualTo("/something")) - .inScenario("foo") // then we return a success + // Then we return a success + .inScenario("foo") .whenScenarioStateIs("RETRY_AFTER_DELAY") .willReturn(ok()) .willSetStateTo("COMPLETED") @@ -84,36 +138,33 @@ internal class RetryingHttpClientTest { RetryingHttpClient.builder().httpClient(httpClient).maxRetries(2).build() val response = - if (async) retryingClient.executeAsync(request).get() - else retryingClient.execute(request) + retryingClient.execute( + HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build(), + async, + ) assertThat(response.statusCode()).isEqualTo(200) verify( 1, postRequestedFor(urlPathEqualTo("/something")) - .withHeader("x-stainless-retry-count", equalTo("0")) + .withHeader("x-stainless-retry-count", equalTo("0")), ) verify( 1, postRequestedFor(urlPathEqualTo("/something")) - .withHeader("x-stainless-retry-count", equalTo("1")) + .withHeader("x-stainless-retry-count", equalTo("1")), ) verify( 1, postRequestedFor(urlPathEqualTo("/something")) - .withHeader("x-stainless-retry-count", equalTo("2")) + .withHeader("x-stainless-retry-count", equalTo("2")), ) + assertNoResponseLeaks() } @ParameterizedTest @ValueSource(booleans = [false, true]) - fun overwriteRetryCountHeader(async: Boolean) { - val request = - HttpRequest.builder() - .method(HttpMethod.POST) - .addPathSegment("something") - .putHeader("x-stainless-retry-count", "42") - .build() + fun execute_withOverwrittenRetryCountHeader(async: Boolean) { stubFor( post(urlPathEqualTo("/something")) .inScenario("foo") // first we fail with a retry after header given as a date @@ -134,21 +185,27 @@ internal class RetryingHttpClientTest { RetryingHttpClient.builder().httpClient(httpClient).maxRetries(2).build() val response = - if (async) retryingClient.executeAsync(request).get() - else retryingClient.execute(request) + retryingClient.execute( + HttpRequest.builder() + .method(HttpMethod.POST) + .addPathSegment("something") + .putHeader("x-stainless-retry-count", "42") + .build(), + async, + ) assertThat(response.statusCode()).isEqualTo(200) verify( 2, postRequestedFor(urlPathEqualTo("/something")) - .withHeader("x-stainless-retry-count", equalTo("42")) + .withHeader("x-stainless-retry-count", equalTo("42")), ) + assertNoResponseLeaks() } - @Test - fun retryAfterMsHeader() { - val request = - HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build() + @ParameterizedTest + @ValueSource(booleans = [false, true]) + fun execute_withRetryAfterMsHeader(async: Boolean) { stubFor( post(urlPathEqualTo("/something")) .inScenario("foo") @@ -165,8 +222,22 @@ internal class RetryingHttpClientTest { ) val retryingClient = RetryingHttpClient.builder().httpClient(httpClient).maxRetries(1).build() - val response = retryingClient.execute(request) + + val response = + retryingClient.execute( + HttpRequest.builder().method(HttpMethod.POST).addPathSegment("something").build(), + async, + ) + assertThat(response.statusCode()).isEqualTo(200) verify(2, postRequestedFor(urlPathEqualTo("/something"))) + assertNoResponseLeaks() } + + private fun HttpClient.execute(request: HttpRequest, async: Boolean): HttpResponse = + if (async) executeAsync(request).get() else execute(request) + + // When retrying, all failed responses should be closed. Only the final returned response should + // be open. + private fun assertNoResponseLeaks() = assertThat(openResponseCount).isEqualTo(1) } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/SerializerTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/SerializerTest.kt index f1c1f965..824c8711 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/SerializerTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/core/http/SerializerTest.kt @@ -48,11 +48,7 @@ internal class SerializerTest { override fun hashCode(): Int { if (hashCode == 0) { - hashCode = - Objects.hash( - isActive, - additionalProperties, - ) + hashCode = Objects.hash(isActive, additionalProperties) } return hashCode } @@ -65,7 +61,8 @@ internal class SerializerTest { } @NoAutoDetect - class Builder { + class Builder internal constructor() { + private var isActive: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -90,10 +87,7 @@ internal class SerializerTest { } fun build(): ClassWithBooleanFieldPrefixedWithIs = - ClassWithBooleanFieldPrefixedWithIs( - isActive, - additionalProperties.toUnmodifiable(), - ) + ClassWithBooleanFieldPrefixedWithIs(isActive, additionalProperties.toImmutable()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AISecretTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AISecretTest.kt index 06232123..d7241b89 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AISecretTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AISecretTest.kt @@ -2,31 +2,43 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AISecretTest { +internal class AISecretTest { @Test fun createAISecret() { - val aISecret = + val aiSecret = AISecret.builder() .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .metadata(AISecret.Metadata.builder().build()) + .metadata( + AISecret.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .previewSecret("preview_secret") .type("type") + .updatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .build() - assertThat(aISecret).isNotNull - assertThat(aISecret.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(aISecret.name()).isEqualTo("name") - assertThat(aISecret.orgId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(aISecret.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(aISecret.metadata()).contains(AISecret.Metadata.builder().build()) - assertThat(aISecret.previewSecret()).contains("preview_secret") - assertThat(aISecret.type()).contains("type") + assertThat(aiSecret).isNotNull + assertThat(aiSecret.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(aiSecret.name()).isEqualTo("name") + assertThat(aiSecret.orgId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(aiSecret.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(aiSecret.metadata()) + .contains( + AISecret.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(aiSecret.previewSecret()).contains("preview_secret") + assertThat(aiSecret.type()).contains("type") + assertThat(aiSecret.updatedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateParamsTest.kt index 7fe6d87f..fefded29 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateParamsTest.kt @@ -2,112 +2,94 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclBatchUpdateParamsTest { +internal class AclBatchUpdateParamsTest { @Test - fun createAclBatchUpdateParams() { + fun create() { AclBatchUpdateParams.builder() - .addAcls( - listOf( + .addAddAcl( + AclBatchUpdateParams.AddAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + .addRemoveAcl( + AclBatchUpdateParams.RemoveAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + .build() + } + + @Test + fun body() { + val params = + AclBatchUpdateParams.builder() + .addAddAcl( AclBatchUpdateParams.AddAcl.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.AddAcl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.AddAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.AddAcl.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - ) - .removeAcls( - listOf( + .addRemoveAcl( AclBatchUpdateParams.RemoveAcl.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.RemoveAcl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.RemoveAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.RemoveAcl.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - ) - .build() - } - - @Test - fun getBody() { - val params = - AclBatchUpdateParams.builder() - .addAcls( - listOf( - AclBatchUpdateParams.AddAcl.builder() - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.AddAcl.ObjectType.ORGANIZATION) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.AddAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.AddAcl.RestrictObjectType.ORGANIZATION - ) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) - ) - .removeAcls( - listOf( - AclBatchUpdateParams.RemoveAcl.builder() - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.RemoveAcl.ObjectType.ORGANIZATION) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.RemoveAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.RemoveAcl.RestrictObjectType.ORGANIZATION - ) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) - ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.addAcls()) - .isEqualTo( + .contains( listOf( AclBatchUpdateParams.AddAcl.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.AddAcl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.AddAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.AddAcl.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) ) assertThat(body.removeAcls()) - .isEqualTo( + .contains( listOf( AclBatchUpdateParams.RemoveAcl.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.RemoveAcl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.RemoveAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.RemoveAcl.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() @@ -116,9 +98,11 @@ class AclBatchUpdateParamsTest { } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AclBatchUpdateParams.builder().build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponseTest.kt index a6d7aec5..b04bfa85 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclBatchUpdateResponseTest.kt @@ -6,43 +6,39 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclBatchUpdateResponseTest { +internal class AclBatchUpdateResponseTest { @Test fun createAclBatchUpdateResponse() { val aclBatchUpdateResponse = AclBatchUpdateResponse.builder() - .addedAcls( - listOf( - Acl.builder() - .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Acl.ObjectType.ORGANIZATION) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(Acl.Permission.CREATE) - .restrictObjectType(Acl.RestrictObjectType.ORGANIZATION) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) + .addAddedAcl( + Acl.builder() + .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - .removedAcls( - listOf( - Acl.builder() - .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Acl.ObjectType.ORGANIZATION) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(Acl.Permission.CREATE) - .restrictObjectType(Acl.RestrictObjectType.ORGANIZATION) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) + .addRemovedAcl( + Acl.builder() + .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) .build() assertThat(aclBatchUpdateResponse).isNotNull @@ -52,11 +48,11 @@ class AclBatchUpdateResponseTest { .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Acl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(Acl.Permission.CREATE) - .restrictObjectType(Acl.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() @@ -67,11 +63,11 @@ class AclBatchUpdateResponseTest { .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Acl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(Acl.Permission.CREATE) - .restrictObjectType(Acl.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclCreateParamsTest.kt index 95dcb724..20eb299f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclCreateParamsTest.kt @@ -2,59 +2,62 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclCreateParamsTest { +internal class AclCreateParamsTest { @Test - fun createAclCreateParams() { + fun create() { AclCreateParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclCreateParams.Permission.CREATE) - .restrictObjectType(AclCreateParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getBody() { + fun body() { val params = AclCreateParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclCreateParams.Permission.CREATE) - .restrictObjectType(AclCreateParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(AclCreateParams.ObjectType.ORGANIZATION) - assertThat(body.groupId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.permission()).isEqualTo(AclCreateParams.Permission.CREATE) - assertThat(body.restrictObjectType()) - .isEqualTo(AclCreateParams.RestrictObjectType.ORGANIZATION) - assertThat(body.roleId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.groupId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.permission()).contains(Permission.CREATE) + assertThat(body.restrictObjectType()).contains(AclObjectType.ORGANIZATION) + assertThat(body.roleId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AclCreateParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(AclCreateParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclDeleteParamsTest.kt index 5b65f5d1..a520f8ce 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclDeleteParamsTest { +internal class AclDeleteParamsTest { @Test - fun createAclDeleteParams() { + fun create() { AclDeleteParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParamsTest.kt index 90f45c40..d6b03177 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclFindAndDeleteParamsTest.kt @@ -2,59 +2,62 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclFindAndDeleteParamsTest { +internal class AclFindAndDeleteParamsTest { @Test - fun createAclFindAndDeleteParams() { + fun create() { AclFindAndDeleteParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclFindAndDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclFindAndDeleteParams.Permission.CREATE) - .restrictObjectType(AclFindAndDeleteParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getBody() { + fun body() { val params = AclFindAndDeleteParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclFindAndDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclFindAndDeleteParams.Permission.CREATE) - .restrictObjectType(AclFindAndDeleteParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(AclFindAndDeleteParams.ObjectType.ORGANIZATION) - assertThat(body.groupId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.permission()).isEqualTo(AclFindAndDeleteParams.Permission.CREATE) - assertThat(body.restrictObjectType()) - .isEqualTo(AclFindAndDeleteParams.RestrictObjectType.ORGANIZATION) - assertThat(body.roleId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.groupId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.permission()).contains(Permission.CREATE) + assertThat(body.restrictObjectType()).contains(AclObjectType.ORGANIZATION) + assertThat(body.roleId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AclFindAndDeleteParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclFindAndDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(AclFindAndDeleteParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclListParamsTest.kt index cc02b4b4..e5288078 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclListParamsTest.kt @@ -2,58 +2,67 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclListParamsTest { +internal class AclListParamsTest { @Test - fun createAclListParams() { + fun create() { AclListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(AclListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = AclListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(AclListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(AclListParams.ObjectType.ORGANIZATION.toString())) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf(AclListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = AclListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(AclListParams.ObjectType.ORGANIZATION.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .build() + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclRetrieveParamsTest.kt index ed334cc7..8ad3dfac 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclRetrieveParamsTest { +internal class AclRetrieveParamsTest { @Test - fun createAclRetrieveParams() { + fun create() { AclRetrieveParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclTest.kt index cedb7fe5..39258080 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AclTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AclTest { +internal class AclTest { @Test fun createAcl() { @@ -15,11 +15,11 @@ class AclTest { .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") ._objectOrgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Acl.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(Acl.Permission.CREATE) - .restrictObjectType(Acl.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() @@ -27,11 +27,11 @@ class AclTest { assertThat(acl.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(acl._objectOrgId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(acl.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(acl.objectType()).isEqualTo(Acl.ObjectType.ORGANIZATION) + assertThat(acl.objectType()).isEqualTo(AclObjectType.ORGANIZATION) assertThat(acl.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(acl.groupId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(acl.permission()).contains(Acl.Permission.CREATE) - assertThat(acl.restrictObjectType()).contains(Acl.RestrictObjectType.ORGANIZATION) + assertThat(acl.permission()).contains(Permission.CREATE) + assertThat(acl.restrictObjectType()).contains(AclObjectType.ORGANIZATION) assertThat(acl.roleId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(acl.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretCreateParamsTest.kt index 803786eb..d91d0d19 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretCreateParamsTest.kt @@ -2,17 +2,22 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretCreateParamsTest { +internal class AiSecretCreateParamsTest { @Test - fun createAiSecretCreateParams() { + fun create() { AiSecretCreateParams.builder() .name("name") - .metadata(AiSecretCreateParams.Metadata.builder().build()) + .metadata( + AiSecretCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") @@ -20,29 +25,42 @@ class AiSecretCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = AiSecretCreateParams.builder() .name("name") - .metadata(AiSecretCreateParams.Metadata.builder().build()) + .metadata( + AiSecretCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") - assertThat(body.metadata()).isEqualTo(AiSecretCreateParams.Metadata.builder().build()) - assertThat(body.orgName()).isEqualTo("org_name") - assertThat(body.secret()).isEqualTo("secret") - assertThat(body.type()).isEqualTo("type") + assertThat(body.metadata()) + .contains( + AiSecretCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.orgName()).contains("org_name") + assertThat(body.secret()).contains("secret") + assertThat(body.type()).contains("type") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AiSecretCreateParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretDeleteParamsTest.kt index 5f984b71..2d9d6f3a 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretDeleteParamsTest { +internal class AiSecretDeleteParamsTest { @Test - fun createAiSecretDeleteParams() { + fun create() { AiSecretDeleteParams.builder().aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParamsTest.kt index e3e4da8a..d7365a0b 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretFindAndDeleteParamsTest.kt @@ -2,31 +2,35 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretFindAndDeleteParamsTest { +internal class AiSecretFindAndDeleteParamsTest { @Test - fun createAiSecretFindAndDeleteParams() { + fun create() { AiSecretFindAndDeleteParams.builder().name("name").orgName("org_name").build() } @Test - fun getBody() { + fun body() { val params = AiSecretFindAndDeleteParams.builder().name("name").orgName("org_name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") - assertThat(body.orgName()).isEqualTo("org_name") + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AiSecretFindAndDeleteParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretListParamsTest.kt index 27820e93..20af378c 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretListParamsTest.kt @@ -2,60 +2,60 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretListParamsTest { +internal class AiSecretListParamsTest { @Test - fun createAiSecretListParams() { + fun create() { AiSecretListParams.builder() .aiSecretName("ai_secret_name") - .aiSecretType(AiSecretListParams.AiSecretType.ofString("string")) + .aiSecretType("string") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(AiSecretListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = AiSecretListParams.builder() .aiSecretName("ai_secret_name") - .aiSecretType(AiSecretListParams.AiSecretType.ofString("string")) + .aiSecretType("string") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(AiSecretListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ai_secret_name", listOf("ai_secret_name")) - expected.put( - "ai_secret_type", - listOf(AiSecretListParams.AiSecretType.ofString("string").toString()) - ) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - AiSecretListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ai_secret_name", "ai_secret_name") + .put("ai_secret_type", "string") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = AiSecretListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretReplaceParamsTest.kt index 3204ee97..cde09c24 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretReplaceParamsTest.kt @@ -2,17 +2,22 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretReplaceParamsTest { +internal class AiSecretReplaceParamsTest { @Test - fun createAiSecretReplaceParams() { + fun create() { AiSecretReplaceParams.builder() .name("name") - .metadata(AiSecretReplaceParams.Metadata.builder().build()) + .metadata( + AiSecretReplaceParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") @@ -20,29 +25,42 @@ class AiSecretReplaceParamsTest { } @Test - fun getBody() { + fun body() { val params = AiSecretReplaceParams.builder() .name("name") - .metadata(AiSecretReplaceParams.Metadata.builder().build()) + .metadata( + AiSecretReplaceParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") - assertThat(body.metadata()).isEqualTo(AiSecretReplaceParams.Metadata.builder().build()) - assertThat(body.orgName()).isEqualTo("org_name") - assertThat(body.secret()).isEqualTo("secret") - assertThat(body.type()).isEqualTo("type") + assertThat(body.metadata()) + .contains( + AiSecretReplaceParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.orgName()).contains("org_name") + assertThat(body.secret()).contains("secret") + assertThat(body.type()).contains("type") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AiSecretReplaceParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParamsTest.kt index c2a28575..a9f2f2aa 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretRetrieveParamsTest { +internal class AiSecretRetrieveParamsTest { @Test - fun createAiSecretRetrieveParams() { + fun create() { AiSecretRetrieveParams.builder().aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretUpdateParamsTest.kt index d324f0a2..627ea2bf 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/AiSecretUpdateParamsTest.kt @@ -2,17 +2,22 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class AiSecretUpdateParamsTest { +internal class AiSecretUpdateParamsTest { @Test - fun createAiSecretUpdateParams() { + fun create() { AiSecretUpdateParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .metadata(AiSecretUpdateParams.Metadata.builder().build()) + .metadata( + AiSecretUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .secret("secret") .type("type") @@ -20,31 +25,44 @@ class AiSecretUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = AiSecretUpdateParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .metadata(AiSecretUpdateParams.Metadata.builder().build()) + .metadata( + AiSecretUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .secret("secret") .type("type") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.metadata()).isEqualTo(AiSecretUpdateParams.Metadata.builder().build()) - assertThat(body.name()).isEqualTo("name") - assertThat(body.secret()).isEqualTo("secret") - assertThat(body.type()).isEqualTo("type") + + val body = params._body() + + assertNotNull(body) + assertThat(body.metadata()) + .contains( + AiSecretUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.name()).contains("name") + assertThat(body.secret()).contains("secret") + assertThat(body.type()).contains("type") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = AiSecretUpdateParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyCreateParamsTest.kt index 8c337a43..315dc13b 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyCreateParamsTest.kt @@ -2,31 +2,35 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ApiKeyCreateParamsTest { +internal class ApiKeyCreateParamsTest { @Test - fun createApiKeyCreateParams() { + fun create() { ApiKeyCreateParams.builder().name("name").orgName("org_name").build() } @Test - fun getBody() { + fun body() { val params = ApiKeyCreateParams.builder().name("name").orgName("org_name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") - assertThat(body.orgName()).isEqualTo("org_name") + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ApiKeyCreateParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParamsTest.kt index bbcd063d..f7546c55 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ApiKeyDeleteParamsTest { +internal class ApiKeyDeleteParamsTest { @Test - fun createApiKeyDeleteParams() { + fun create() { ApiKeyDeleteParams.builder().apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyListParamsTest.kt index e749c8e0..e9582d7c 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyListParamsTest.kt @@ -2,52 +2,57 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ApiKeyListParamsTest { +internal class ApiKeyListParamsTest { @Test - fun createApiKeyListParams() { + fun create() { ApiKeyListParams.builder() .apiKeyName("api_key_name") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ApiKeyListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = ApiKeyListParams.builder() .apiKeyName("api_key_name") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ApiKeyListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("api_key_name", listOf("api_key_name")) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf(ApiKeyListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("api_key_name", "api_key_name") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ApiKeyListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParamsTest.kt index 48a5016b..f5ca88f6 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ApiKeyRetrieveParamsTest { +internal class ApiKeyRetrieveParamsTest { @Test - fun createApiKeyRetrieveParams() { + fun create() { ApiKeyRetrieveParams.builder().apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyTest.kt index 5d9ab3b9..099b0e65 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ApiKeyTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ApiKeyTest { +internal class ApiKeyTest { @Test fun createApiKey() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImageTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImageTest.kt index fbf9f7e4..b826be89 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImageTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartImageTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ChatCompletionContentPartImageTest { +internal class ChatCompletionContentPartImageTest { @Test fun createChatCompletionContentPartImage() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartTextTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartTextTest.kt index 5e71c215..2e8d9c23 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartTextTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionContentPartTextTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ChatCompletionContentPartTextTest { +internal class ChatCompletionContentPartTextTest { @Test fun createChatCompletionContentPartText() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCallTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCallTest.kt index c609ef38..b140cc39 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCallTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ChatCompletionMessageToolCallTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ChatCompletionMessageToolCallTest { +internal class ChatCompletionMessageToolCallTest { @Test fun createChatCompletionMessageToolCall() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CodeBundleTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CodeBundleTest.kt index 539185e1..5eb775e3 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CodeBundleTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CodeBundleTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class CodeBundleTest { +internal class CodeBundleTest { @Test fun createCodeBundle() { @@ -13,17 +13,15 @@ class CodeBundleTest { CodeBundle.builder() .bundleId("bundle_id") .location( - CodeBundle.Location.ofExperiment( - CodeBundle.Location.Experiment.builder() - .evalName("eval_name") - .position( - CodeBundle.Location.Experiment.Position.ofTask( - Task.builder().type(Task.Type.TASK).build() - ) - ) - .type(CodeBundle.Location.Experiment.Type.EXPERIMENT) - .build() - ) + CodeBundle.Location.Experiment.builder() + .evalName("eval_name") + .position( + CodeBundle.Location.Experiment.Position.Type.builder() + .type(CodeBundle.Location.Experiment.Position.Type.InnerType.TASK) + .build() + ) + .type(CodeBundle.Location.Experiment.Type.EXPERIMENT) + .build() ) .runtimeContext( CodeBundle.RuntimeContext.builder() @@ -41,9 +39,9 @@ class CodeBundleTest { CodeBundle.Location.Experiment.builder() .evalName("eval_name") .position( - CodeBundle.Location.Experiment.Position.ofTask( - Task.builder().type(Task.Type.TASK).build() - ) + CodeBundle.Location.Experiment.Position.Type.builder() + .type(CodeBundle.Location.Experiment.Position.Type.InnerType.TASK) + .build() ) .type(CodeBundle.Location.Experiment.Type.EXPERIMENT) .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CreateApiKeyOutputTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CreateApiKeyOutputTest.kt index 6bfead25..f9057687 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CreateApiKeyOutputTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CreateApiKeyOutputTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class CreateApiKeyOutputTest { +internal class CreateApiKeyOutputTest { @Test fun createCreateApiKeyOutput() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponseTest.kt index dca2c6ff..4abcfb9d 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/CrossObjectInsertResponseTest.kt @@ -2,25 +2,68 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class CrossObjectInsertResponseTest { +internal class CrossObjectInsertResponseTest { @Test fun createCrossObjectInsertResponse() { val crossObjectInsertResponse = CrossObjectInsertResponse.builder() - .dataset(CrossObjectInsertResponse.Dataset.builder().build()) - .experiment(CrossObjectInsertResponse.Experiment.builder().build()) - .projectLogs(CrossObjectInsertResponse.ProjectLogs.builder().build()) + .dataset( + CrossObjectInsertResponse.Dataset.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) + .experiment( + CrossObjectInsertResponse.Experiment.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) + .projectLogs( + CrossObjectInsertResponse.ProjectLogs.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) .build() assertThat(crossObjectInsertResponse).isNotNull assertThat(crossObjectInsertResponse.dataset()) - .contains(CrossObjectInsertResponse.Dataset.builder().build()) + .contains( + CrossObjectInsertResponse.Dataset.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) assertThat(crossObjectInsertResponse.experiment()) - .contains(CrossObjectInsertResponse.Experiment.builder().build()) + .contains( + CrossObjectInsertResponse.Experiment.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) assertThat(crossObjectInsertResponse.projectLogs()) - .contains(CrossObjectInsertResponse.ProjectLogs.builder().build()) + .contains( + CrossObjectInsertResponse.ProjectLogs.builder() + .putAdditionalProperty( + "foo", + JsonValue.from(mapOf("row_ids" to listOf("string"))), + ) + .build() + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DataSummaryTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DataSummaryTest.kt index 544c8f05..f7759625 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DataSummaryTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DataSummaryTest.kt @@ -5,12 +5,12 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DataSummaryTest { +internal class DataSummaryTest { @Test fun createDataSummary() { - val dataSummary = DataSummary.builder().totalRecords(123L).build() + val dataSummary = DataSummary.builder().totalRecords(0L).build() assertThat(dataSummary).isNotNull - assertThat(dataSummary.totalRecords()).isEqualTo(123L) + assertThat(dataSummary.totalRecords()).isEqualTo(0L) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetCreateParamsTest.kt index cd299934..e9bd56e1 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetCreateParamsTest.kt @@ -2,46 +2,67 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetCreateParamsTest { +internal class DatasetCreateParamsTest { @Test - fun createDatasetCreateParams() { + fun create() { DatasetCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") + .metadata( + DatasetCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() } @Test - fun getBody() { + fun body() { val params = DatasetCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") + .metadata( + DatasetCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.description()).isEqualTo("description") + assertThat(body.description()).contains("description") + assertThat(body.metadata()) + .contains( + DatasetCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = DatasetCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetDeleteParamsTest.kt index bb209233..1d74f765 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetDeleteParamsTest { +internal class DatasetDeleteParamsTest { @Test - fun createDatasetDeleteParams() { + fun create() { DatasetDeleteParams.builder().datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetEventTest.kt index 3ac2cceb..14d3a5c7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetEventTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetEventTest.kt @@ -2,12 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetEventTest { +internal class DatasetEventTest { @Test fun createDatasetEvent() { @@ -20,10 +20,20 @@ class DatasetEventTest { .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .rootSpanId("root_span_id") .spanId("span_id") - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(DatasetEvent.Metadata.builder().build()) - .tags(listOf("string")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(DatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .addTag("string") .build() assertThat(datasetEvent).isNotNull assertThat(datasetEvent.id()).isEqualTo("id") @@ -34,9 +44,21 @@ class DatasetEventTest { assertThat(datasetEvent.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(datasetEvent.rootSpanId()).isEqualTo("root_span_id") assertThat(datasetEvent.spanId()).isEqualTo("span_id") - assertThat(datasetEvent._expected()).isEqualTo(JsonNull.of()) - assertThat(datasetEvent._input()).isEqualTo(JsonNull.of()) - assertThat(datasetEvent.metadata()).contains(DatasetEvent.Metadata.builder().build()) + assertThat(datasetEvent._expected()).isEqualTo(JsonValue.from(mapOf())) + assertThat(datasetEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(datasetEvent.isRoot()).contains(true) + assertThat(datasetEvent.metadata()) + .contains(DatasetEvent.Metadata.builder().model("model").build()) + assertThat(datasetEvent.origin()) + .contains( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) assertThat(datasetEvent.tags().get()).containsExactly("string") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFeedbackParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFeedbackParamsTest.kt index e5ec92fd..5c8d41e3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFeedbackParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFeedbackParamsTest.kt @@ -2,69 +2,85 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetFeedbackParamsTest { +internal class DatasetFeedbackParamsTest { @Test - fun createDatasetFeedbackParams() { + fun create() { DatasetFeedbackParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackDatasetItem.builder() - .id("id") - .comment("comment") - .metadata(FeedbackDatasetItem.Metadata.builder().build()) - .source(FeedbackDatasetItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackDatasetItem.builder() + .id("id") + .comment("comment") + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .source(FeedbackDatasetItem.Source.APP) + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = DatasetFeedbackParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackDatasetItem.builder() - .id("id") - .comment("comment") - .metadata(FeedbackDatasetItem.Metadata.builder().build()) - .source(FeedbackDatasetItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackDatasetItem.builder() + .id("id") + .comment("comment") + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .source(FeedbackDatasetItem.Source.APP) + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo( listOf( FeedbackDatasetItem.builder() .id("id") .comment("comment") - .metadata(FeedbackDatasetItem.Metadata.builder().build()) + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .source(FeedbackDatasetItem.Source.APP) + .addTag("string") .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = DatasetFeedbackParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackDatasetItem.builder().id("id").build())) + .addFeedback(FeedbackDatasetItem.builder().id("id").build()) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo(listOf(FeedbackDatasetItem.builder().id("id").build())) } @@ -74,7 +90,7 @@ class DatasetFeedbackParamsTest { val params = DatasetFeedbackParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackDatasetItem.builder().id("id").build())) + .addFeedback(FeedbackDatasetItem.builder().id("id").build()) .build() assertThat(params).isNotNull // path param "datasetId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchParamsTest.kt index 260bb3bb..1c31fd85 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchParamsTest.kt @@ -2,17 +2,17 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetFetchParamsTest { +internal class DatasetFetchParamsTest { @Test - fun createDatasetFetchParams() { + fun create() { DatasetFetchParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -20,29 +20,37 @@ class DatasetFetchParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = DatasetFetchParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val expected = mutableMapOf>() - expected.put("limit", listOf("123")) - expected.put("max_root_span_id", listOf("max_root_span_id")) - expected.put("max_xact_id", listOf("max_xact_id")) - expected.put("version", listOf("version")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("limit", "0") + .put("max_root_span_id", "max_root_span_id") + .put("max_xact_id", "max_xact_id") + .put("version", "version") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = DatasetFetchParams.builder().datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchPostParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchPostParamsTest.kt index cc6494aa..53eeec48 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchPostParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetFetchPostParamsTest.kt @@ -2,28 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetFetchPostParamsTest { +internal class DatasetFetchPostParamsTest { @Test - fun createDatasetFetchPostParams() { + fun create() { DatasetFetchPostParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -31,52 +21,37 @@ class DatasetFetchPostParamsTest { } @Test - fun getBody() { + fun body() { val params = DatasetFetchPostParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.cursor()).isEqualTo("cursor") - assertThat(body.filters()) - .isEqualTo( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - assertThat(body.limit()).isEqualTo(123L) - assertThat(body.maxRootSpanId()).isEqualTo("max_root_span_id") - assertThat(body.maxXactId()).isEqualTo("max_xact_id") - assertThat(body.version()).isEqualTo("version") + + val body = params._body() + + assertNotNull(body) + assertThat(body.cursor()).contains("cursor") + assertThat(body.limit()).contains(0L) + assertThat(body.maxRootSpanId()).contains("max_root_span_id") + assertThat(body.maxXactId()).contains("max_xact_id") + assertThat(body.version()).contains("version") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = DatasetFetchPostParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetInsertParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetInsertParamsTest.kt index 69c688b4..4b535b10 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetInsertParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetInsertParamsTest.kt @@ -2,106 +2,126 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetInsertParamsTest { +internal class DatasetInsertParamsTest { @Test - fun createDatasetInsertParams() { + fun create() { DatasetInsertParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder() + .addEvent( + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventReplace.Metadata.builder().build()) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = DatasetInsertParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder() + .addEvent( + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventReplace.Metadata.builder().build()) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.events()) .isEqualTo( listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventReplace.Metadata.builder().build()) - .tags(listOf("string")) - .build() - ) + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = DatasetInsertParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertDatasetEvent.builder().build()) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.events()) - .isEqualTo( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder().build() - ) - ) - ) + + val body = params._body() + + assertNotNull(body) + assertThat(body.events()).isEqualTo(listOf(InsertDatasetEvent.builder().build())) } @Test @@ -109,13 +129,7 @@ class DatasetInsertParamsTest { val params = DatasetInsertParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertDatasetEvent.builder().build()) .build() assertThat(params).isNotNull // path param "datasetId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetListParamsTest.kt index d0963d5e..a6ffbbd4 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetListParamsTest.kt @@ -2,19 +2,19 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetListParamsTest { +internal class DatasetListParamsTest { @Test - fun createDatasetListParams() { + fun create() { DatasetListParams.builder() .datasetName("dataset_name") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(DatasetListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -23,39 +23,42 @@ class DatasetListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = DatasetListParams.builder() .datasetName("dataset_name") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(DatasetListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("dataset_name", listOf("dataset_name")) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - DatasetListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("dataset_name", "dataset_name") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = DatasetListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetRetrieveParamsTest.kt index 776cce3b..147e6451 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetRetrieveParamsTest { +internal class DatasetRetrieveParamsTest { @Test - fun createDatasetRetrieveParams() { + fun create() { DatasetRetrieveParams.builder().datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetSummarizeParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetSummarizeParamsTest.kt index db5cbef2..24bc6c0f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetSummarizeParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetSummarizeParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetSummarizeParamsTest { +internal class DatasetSummarizeParamsTest { @Test - fun createDatasetSummarizeParams() { + fun create() { DatasetSummarizeParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .summarizeData(true) @@ -17,25 +17,29 @@ class DatasetSummarizeParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = DatasetSummarizeParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .summarizeData(true) .build() - val expected = mutableMapOf>() - expected.put("summarize_data", listOf("true")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo(QueryParams.builder().put("summarize_data", "true").build()) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = DatasetSummarizeParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetTest.kt index 59f91add..5751efca 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetTest.kt @@ -2,11 +2,12 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetTest { +internal class DatasetTest { @Test fun createDataset() { @@ -18,7 +19,11 @@ class DatasetTest { .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .description("description") - .metadata(Dataset.Metadata.builder().build()) + .metadata( + Dataset.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() assertThat(dataset).isNotNull @@ -28,7 +33,12 @@ class DatasetTest { assertThat(dataset.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(dataset.deletedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(dataset.description()).contains("description") - assertThat(dataset.metadata()).contains(Dataset.Metadata.builder().build()) + assertThat(dataset.metadata()) + .contains( + Dataset.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(dataset.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetUpdateParamsTest.kt index e8dfdbe0..ebdf0e4f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/DatasetUpdateParamsTest.kt @@ -2,44 +2,62 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class DatasetUpdateParamsTest { +internal class DatasetUpdateParamsTest { @Test - fun createDatasetUpdateParams() { + fun create() { DatasetUpdateParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .metadata(DatasetUpdateParams.Metadata.builder().build()) + .metadata( + DatasetUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .build() } @Test - fun getBody() { + fun body() { val params = DatasetUpdateParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .metadata(DatasetUpdateParams.Metadata.builder().build()) + .metadata( + DatasetUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.description()).isEqualTo("description") - assertThat(body.metadata()).isEqualTo(DatasetUpdateParams.Metadata.builder().build()) - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.description()).contains("description") + assertThat(body.metadata()) + .contains( + DatasetUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.name()).contains("name") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = DatasetUpdateParams.builder().datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarCreateParamsTest.kt index 7700b365..1af40d88 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarCreateParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarCreateParamsTest { +internal class EnvVarCreateParamsTest { @Test - fun createEnvVarCreateParams() { + fun create() { EnvVarCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -19,7 +19,7 @@ class EnvVarCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = EnvVarCreateParams.builder() .name("name") @@ -27,24 +27,28 @@ class EnvVarCreateParamsTest { .objectType(EnvVarCreateParams.ObjectType.ORGANIZATION) .value("value") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.objectType()).isEqualTo(EnvVarCreateParams.ObjectType.ORGANIZATION) - assertThat(body.value()).isEqualTo("value") + assertThat(body.value()).contains("value") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = EnvVarCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectType(EnvVarCreateParams.ObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.objectType()).isEqualTo(EnvVarCreateParams.ObjectType.ORGANIZATION) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarDeleteParamsTest.kt index 29879f19..e7c988b4 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarDeleteParamsTest { +internal class EnvVarDeleteParamsTest { @Test - fun createEnvVarDeleteParams() { + fun create() { EnvVarDeleteParams.builder().envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListParamsTest.kt index f95a36d6..4978303f 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListParamsTest.kt @@ -2,49 +2,54 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarListParamsTest { +internal class EnvVarListParamsTest { @Test - fun createEnvVarListParams() { + fun create() { EnvVarListParams.builder() .envVarName("env_var_name") - .ids(EnvVarListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(EnvVarListParams.ObjectType.ORGANIZATION) + .objectType(EnvVarObjectType.ORGANIZATION) .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = EnvVarListParams.builder() .envVarName("env_var_name") - .ids(EnvVarListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(EnvVarListParams.ObjectType.ORGANIZATION) + .objectType(EnvVarObjectType.ORGANIZATION) .build() - val expected = mutableMapOf>() - expected.put("env_var_name", listOf("env_var_name")) - expected.put( - "ids", - listOf(EnvVarListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(EnvVarListParams.ObjectType.ORGANIZATION.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("env_var_name", "env_var_name") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = EnvVarListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListResponseTest.kt index 0024324f..801245e2 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarListResponseTest.kt @@ -6,23 +6,21 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarListResponseTest { +internal class EnvVarListResponseTest { @Test fun createEnvVarListResponse() { val envVarListResponse = EnvVarListResponse.builder() - .objects( - listOf( - EnvVar.builder() - .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .name("name") - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(EnvVar.ObjectType.ORGANIZATION) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .used(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .build() - ) + .addObject( + EnvVar.builder() + .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .name("name") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(EnvVar.ObjectType.ORGANIZATION) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .used(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() ) .build() assertThat(envVarListResponse).isNotNull diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarReplaceParamsTest.kt index 7be569fb..74d5e35f 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarReplaceParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarReplaceParamsTest { +internal class EnvVarReplaceParamsTest { @Test - fun createEnvVarReplaceParams() { + fun create() { EnvVarReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -19,7 +19,7 @@ class EnvVarReplaceParamsTest { } @Test - fun getBody() { + fun body() { val params = EnvVarReplaceParams.builder() .name("name") @@ -27,24 +27,28 @@ class EnvVarReplaceParamsTest { .objectType(EnvVarReplaceParams.ObjectType.ORGANIZATION) .value("value") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.objectType()).isEqualTo(EnvVarReplaceParams.ObjectType.ORGANIZATION) - assertThat(body.value()).isEqualTo("value") + assertThat(body.value()).contains("value") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = EnvVarReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectType(EnvVarReplaceParams.ObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.objectType()).isEqualTo(EnvVarReplaceParams.ObjectType.ORGANIZATION) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParamsTest.kt index 52c6148b..d2eee241 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarRetrieveParamsTest { +internal class EnvVarRetrieveParamsTest { @Test - fun createEnvVarRetrieveParams() { + fun create() { EnvVarRetrieveParams.builder().envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarTest.kt index 224dddbb..6df9126a 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarTest { +internal class EnvVarTest { @Test fun createEnvVar() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarUpdateParamsTest.kt index 3ebce16f..81bdf42a 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EnvVarUpdateParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EnvVarUpdateParamsTest { +internal class EnvVarUpdateParamsTest { @Test - fun createEnvVarUpdateParams() { + fun create() { EnvVarUpdateParams.builder() .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") @@ -18,28 +18,32 @@ class EnvVarUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = EnvVarUpdateParams.builder() .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") .value("value") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") - assertThat(body.value()).isEqualTo("value") + assertThat(body.value()).contains("value") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = EnvVarUpdateParams.builder() .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EvalCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EvalCreateParamsTest.kt index 84d240e6..ec0f8d22 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EvalCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/EvalCreateParamsTest.kt @@ -2,83 +2,190 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class EvalCreateParamsTest { +internal class EvalCreateParamsTest { @Test - fun createEvalCreateParams() { + fun create() { EvalCreateParams.builder() .data( - EvalCreateParams.Data.ofDatasetId( - EvalCreateParams.Data.DatasetId.builder().datasetId("dataset_id").build() - ) - ) - .projectId("project_id") - .scores( - listOf( - EvalCreateParams.Score.ofFunctionId( - EvalCreateParams.Score.FunctionId.builder() - .functionId("function_id") - .version("version") + EvalCreateParams.Data.DatasetId.builder() + .datasetId("dataset_id") + ._internalBtql( + EvalCreateParams.Data.DatasetId._InternalBtql + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) - ) + .build() + ) + .projectId("project_id") + .addScore( + EvalCreateParams.Score.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) .task( - EvalCreateParams.Task.ofFunctionId( - EvalCreateParams.Task.FunctionId.builder() - .functionId("function_id") - .version("version") - .build() - ) + EvalCreateParams.Task.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) + .baseExperimentId("base_experiment_id") + .baseExperimentName("base_experiment_name") .experimentName("experiment_name") - .metadata(EvalCreateParams.Metadata.builder().build()) + .gitMetadataSettings( + EvalCreateParams.GitMetadataSettings.builder() + .collect(EvalCreateParams.GitMetadataSettings.Collect.ALL) + .addField(EvalCreateParams.GitMetadataSettings.Field.COMMIT) + .build() + ) + .isPublic(true) + .maxConcurrency(0.0) + .metadata( + EvalCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .parent( + EvalCreateParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType(EvalCreateParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS) + .propagatedEvent( + EvalCreateParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + EvalCreateParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) .stream(true) + .timeout(0.0) + .trialCount(0.0) .build() } @Test - fun getBody() { + fun body() { val params = EvalCreateParams.builder() .data( - EvalCreateParams.Data.ofDatasetId( - EvalCreateParams.Data.DatasetId.builder().datasetId("dataset_id").build() - ) - ) - .projectId("project_id") - .scores( - listOf( - EvalCreateParams.Score.ofFunctionId( - EvalCreateParams.Score.FunctionId.builder() - .functionId("function_id") - .version("version") + EvalCreateParams.Data.DatasetId.builder() + .datasetId("dataset_id") + ._internalBtql( + EvalCreateParams.Data.DatasetId._InternalBtql + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) - ) + .build() + ) + .projectId("project_id") + .addScore( + EvalCreateParams.Score.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) .task( - EvalCreateParams.Task.ofFunctionId( - EvalCreateParams.Task.FunctionId.builder() - .functionId("function_id") - .version("version") - .build() - ) + EvalCreateParams.Task.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) + .baseExperimentId("base_experiment_id") + .baseExperimentName("base_experiment_name") .experimentName("experiment_name") - .metadata(EvalCreateParams.Metadata.builder().build()) + .gitMetadataSettings( + EvalCreateParams.GitMetadataSettings.builder() + .collect(EvalCreateParams.GitMetadataSettings.Collect.ALL) + .addField(EvalCreateParams.GitMetadataSettings.Field.COMMIT) + .build() + ) + .isPublic(true) + .maxConcurrency(0.0) + .metadata( + EvalCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .parent( + EvalCreateParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + EvalCreateParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + EvalCreateParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + EvalCreateParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) .stream(true) + .timeout(0.0) + .trialCount(0.0) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.data()) .isEqualTo( EvalCreateParams.Data.ofDatasetId( - EvalCreateParams.Data.DatasetId.builder().datasetId("dataset_id").build() + EvalCreateParams.Data.DatasetId.builder() + .datasetId("dataset_id") + ._internalBtql( + EvalCreateParams.Data.DatasetId._InternalBtql + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() ) ) assertThat(body.projectId()).isEqualTo("project_id") @@ -102,38 +209,81 @@ class EvalCreateParamsTest { .build() ) ) - assertThat(body.experimentName()).isEqualTo("experiment_name") - assertThat(body.metadata()).isEqualTo(EvalCreateParams.Metadata.builder().build()) - assertThat(body.stream()).isEqualTo(true) + assertThat(body.baseExperimentId()).contains("base_experiment_id") + assertThat(body.baseExperimentName()).contains("base_experiment_name") + assertThat(body.experimentName()).contains("experiment_name") + assertThat(body.gitMetadataSettings()) + .contains( + EvalCreateParams.GitMetadataSettings.builder() + .collect(EvalCreateParams.GitMetadataSettings.Collect.ALL) + .addField(EvalCreateParams.GitMetadataSettings.Field.COMMIT) + .build() + ) + assertThat(body.isPublic()).contains(true) + assertThat(body.maxConcurrency()).contains(0.0) + assertThat(body.metadata()) + .contains( + EvalCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.parent()) + .contains( + EvalCreateParams.Parent.ofSpanParentStruct( + EvalCreateParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + EvalCreateParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + EvalCreateParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + EvalCreateParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + ) + assertThat(body.repoInfo()) + .contains( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) + assertThat(body.stream()).contains(true) + assertThat(body.timeout()).contains(0.0) + assertThat(body.trialCount()).contains(0.0) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = EvalCreateParams.builder() - .data( - EvalCreateParams.Data.ofDatasetId( - EvalCreateParams.Data.DatasetId.builder().datasetId("dataset_id").build() - ) - ) + .data(EvalCreateParams.Data.DatasetId.builder().datasetId("dataset_id").build()) .projectId("project_id") - .scores( - listOf( - EvalCreateParams.Score.ofFunctionId( - EvalCreateParams.Score.FunctionId.builder() - .functionId("function_id") - .build() - ) - ) - ) - .task( - EvalCreateParams.Task.ofFunctionId( - EvalCreateParams.Task.FunctionId.builder().functionId("function_id").build() - ) + .addScore( + EvalCreateParams.Score.FunctionId.builder().functionId("function_id").build() ) + .task(EvalCreateParams.Task.FunctionId.builder().functionId("function_id").build()) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.data()) .isEqualTo( EvalCreateParams.Data.ofDatasetId( diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentCreateParamsTest.kt index 35e96747..d7f74f35 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentCreateParamsTest.kt @@ -2,14 +2,15 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentCreateParamsTest { +internal class ExperimentCreateParamsTest { @Test - fun createExperimentCreateParams() { + fun create() { ExperimentCreateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .baseExpId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -17,8 +18,12 @@ class ExperimentCreateParamsTest { .datasetVersion("dataset_version") .description("description") .ensureNew(true) - .metadata(ExperimentCreateParams.Metadata.builder().build()) - .name("name") + .metadata( + ExperimentCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("x") .public_(true) .repoInfo( RepoInfo.builder() @@ -37,7 +42,7 @@ class ExperimentCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = ExperimentCreateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -46,8 +51,12 @@ class ExperimentCreateParamsTest { .datasetVersion("dataset_version") .description("description") .ensureNew(true) - .metadata(ExperimentCreateParams.Metadata.builder().build()) - .name("name") + .metadata( + ExperimentCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("x") .public_(true) .repoInfo( RepoInfo.builder() @@ -63,19 +72,26 @@ class ExperimentCreateParamsTest { .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.baseExpId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.datasetId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.datasetVersion()).isEqualTo("dataset_version") - assertThat(body.description()).isEqualTo("description") - assertThat(body.ensureNew()).isEqualTo(true) - assertThat(body.metadata()).isEqualTo(ExperimentCreateParams.Metadata.builder().build()) - assertThat(body.name()).isEqualTo("name") - assertThat(body.public_()).isEqualTo(true) + assertThat(body.baseExpId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.datasetId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.datasetVersion()).contains("dataset_version") + assertThat(body.description()).contains("description") + assertThat(body.ensureNew()).contains(true) + assertThat(body.metadata()) + .contains( + ExperimentCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.name()).contains("x") + assertThat(body.public_()).contains(true) assertThat(body.repoInfo()) - .isEqualTo( + .contains( RepoInfo.builder() .authorEmail("author_email") .authorName("author_name") @@ -91,13 +107,15 @@ class ExperimentCreateParamsTest { } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ExperimentCreateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentDeleteParamsTest.kt index 4577db52..cc7edd11 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentDeleteParamsTest { +internal class ExperimentDeleteParamsTest { @Test - fun createExperimentDeleteParams() { + fun create() { ExperimentDeleteParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentEventTest.kt index 8c65509a..bc31377c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentEventTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentEventTest.kt @@ -2,12 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentEventTest { +internal class ExperimentEventTest { @Test fun createExperimentEvent() { @@ -24,33 +24,44 @@ class ExperimentEventTest { ExperimentEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ExperimentEvent.Metadata.builder().build()) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ExperimentEvent.Metadata.builder().model("model").build()) .metrics( ExperimentEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - .output(JsonNull.of()) - .scores(ExperimentEvent.Scores.builder().build()) - .spanAttributes( - ExperimentEvent.SpanAttributes.builder() - .name("name") - .type(ExperimentEvent.SpanAttributes.Type.LLM) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - .spanParents(listOf("string")) - .tags(listOf("string")) + .output(JsonValue.from(mapOf())) + .scores( + ExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + .addSpanParent("string") + .addTag("string") .build() assertThat(experimentEvent).isNotNull assertThat(experimentEvent.id()).isEqualTo("id") @@ -66,33 +77,47 @@ class ExperimentEventTest { ExperimentEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - assertThat(experimentEvent.datasetRecordId()).contains("dataset_record_id") - assertThat(experimentEvent._error()).isEqualTo(JsonNull.of()) - assertThat(experimentEvent._expected()).isEqualTo(JsonNull.of()) - assertThat(experimentEvent._input()).isEqualTo(JsonNull.of()) - assertThat(experimentEvent.metadata()).contains(ExperimentEvent.Metadata.builder().build()) + assertThat(experimentEvent._error()).isEqualTo(JsonValue.from(mapOf())) + assertThat(experimentEvent._expected()).isEqualTo(JsonValue.from(mapOf())) + assertThat(experimentEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(experimentEvent.isRoot()).contains(true) + assertThat(experimentEvent.metadata()) + .contains(ExperimentEvent.Metadata.builder().model("model").build()) assertThat(experimentEvent.metrics()) .contains( ExperimentEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - assertThat(experimentEvent._output()).isEqualTo(JsonNull.of()) - assertThat(experimentEvent.scores()).contains(ExperimentEvent.Scores.builder().build()) - assertThat(experimentEvent.spanAttributes()) + assertThat(experimentEvent.origin()) .contains( - ExperimentEvent.SpanAttributes.builder() - .name("name") - .type(ExperimentEvent.SpanAttributes.Type.LLM) + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) + assertThat(experimentEvent._output()).isEqualTo(JsonValue.from(mapOf())) + assertThat(experimentEvent.scores()) + .contains( + ExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + assertThat(experimentEvent.spanAttributes()) + .contains(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) assertThat(experimentEvent.spanParents().get()).containsExactly("string") assertThat(experimentEvent.tags().get()).containsExactly("string") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParamsTest.kt index b05c51e5..5ce9c787 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFeedbackParamsTest.kt @@ -2,76 +2,103 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentFeedbackParamsTest { +internal class ExperimentFeedbackParamsTest { @Test - fun createExperimentFeedbackParams() { + fun create() { ExperimentFeedbackParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackExperimentItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackExperimentItem.Metadata.builder().build()) - .scores(FeedbackExperimentItem.Scores.builder().build()) - .source(FeedbackExperimentItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackExperimentItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackExperimentItem.Source.APP) + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = ExperimentFeedbackParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackExperimentItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackExperimentItem.Metadata.builder().build()) - .scores(FeedbackExperimentItem.Scores.builder().build()) - .source(FeedbackExperimentItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackExperimentItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackExperimentItem.Source.APP) + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo( listOf( FeedbackExperimentItem.builder() .id("id") .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackExperimentItem.Metadata.builder().build()) - .scores(FeedbackExperimentItem.Scores.builder().build()) + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .source(FeedbackExperimentItem.Source.APP) + .addTag("string") .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ExperimentFeedbackParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackExperimentItem.builder().id("id").build())) + .addFeedback(FeedbackExperimentItem.builder().id("id").build()) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo(listOf(FeedbackExperimentItem.builder().id("id").build())) } @@ -81,7 +108,7 @@ class ExperimentFeedbackParamsTest { val params = ExperimentFeedbackParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackExperimentItem.builder().id("id").build())) + .addFeedback(FeedbackExperimentItem.builder().id("id").build()) .build() assertThat(params).isNotNull // path param "experimentId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchParamsTest.kt index 138cbb6a..a4d0d229 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchParamsTest.kt @@ -2,17 +2,17 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentFetchParamsTest { +internal class ExperimentFetchParamsTest { @Test - fun createExperimentFetchParams() { + fun create() { ExperimentFetchParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -20,31 +20,39 @@ class ExperimentFetchParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ExperimentFetchParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val expected = mutableMapOf>() - expected.put("limit", listOf("123")) - expected.put("max_root_span_id", listOf("max_root_span_id")) - expected.put("max_xact_id", listOf("max_xact_id")) - expected.put("version", listOf("version")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("limit", "0") + .put("max_root_span_id", "max_root_span_id") + .put("max_xact_id", "max_xact_id") + .put("version", "version") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ExperimentFetchParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParamsTest.kt index d48306d8..d8445769 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentFetchPostParamsTest.kt @@ -2,28 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentFetchPostParamsTest { +internal class ExperimentFetchPostParamsTest { @Test - fun createExperimentFetchPostParams() { + fun create() { ExperimentFetchPostParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -31,52 +21,37 @@ class ExperimentFetchPostParamsTest { } @Test - fun getBody() { + fun body() { val params = ExperimentFetchPostParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.cursor()).isEqualTo("cursor") - assertThat(body.filters()) - .isEqualTo( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - assertThat(body.limit()).isEqualTo(123L) - assertThat(body.maxRootSpanId()).isEqualTo("max_root_span_id") - assertThat(body.maxXactId()).isEqualTo("max_xact_id") - assertThat(body.version()).isEqualTo("version") + + val body = params._body() + + assertNotNull(body) + assertThat(body.cursor()).contains("cursor") + assertThat(body.limit()).contains(0L) + assertThat(body.maxRootSpanId()).contains("max_root_span_id") + assertThat(body.maxXactId()).contains("max_xact_id") + assertThat(body.version()).contains("version") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ExperimentFetchPostParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentInsertParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentInsertParamsTest.kt index 80fced9c..aeaadaf0 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentInsertParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentInsertParamsTest.kt @@ -2,184 +2,213 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentInsertParamsTest { +internal class ExperimentInsertParamsTest { @Test - fun createExperimentInsertParams() { + fun create() { ExperimentInsertParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder() + .addEvent( + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertExperimentEvent.Metadata.builder().model("model").build()) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertExperimentEventReplace.Metadata.builder().build()) - .metrics( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventReplace.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = ExperimentInsertParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder() + .addEvent( + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertExperimentEvent.Metadata.builder().model("model").build()) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertExperimentEventReplace.Metadata.builder().build()) - .metrics( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventReplace.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.events()) .isEqualTo( listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertExperimentEventReplace.Metadata.builder().build()) - .metrics( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventReplace.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - ) + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertExperimentEvent.Metadata.builder().model("model").build()) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ExperimentInsertParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertExperimentEvent.builder().build()) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.events()) - .isEqualTo( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder().build() - ) - ) - ) + + val body = params._body() + + assertNotNull(body) + assertThat(body.events()).isEqualTo(listOf(InsertExperimentEvent.builder().build())) } @Test @@ -187,13 +216,7 @@ class ExperimentInsertParamsTest { val params = ExperimentInsertParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertExperimentEvent.builder().build()) .build() assertThat(params).isNotNull // path param "experimentId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentListParamsTest.kt index 2168e880..9c1814c3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentListParamsTest.kt @@ -2,19 +2,19 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentListParamsTest { +internal class ExperimentListParamsTest { @Test - fun createExperimentListParams() { + fun create() { ExperimentListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .experimentName("experiment_name") - .ids(ExperimentListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -23,39 +23,42 @@ class ExperimentListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ExperimentListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .experimentName("experiment_name") - .ids(ExperimentListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("experiment_name", listOf("experiment_name")) - expected.put( - "ids", - listOf( - ExperimentListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("experiment_name", "experiment_name") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ExperimentListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParamsTest.kt index 5efe0624..435a99fd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentRetrieveParamsTest { +internal class ExperimentRetrieveParamsTest { @Test - fun createExperimentRetrieveParams() { + fun create() { ExperimentRetrieveParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParamsTest.kt index d813806c..3260545d 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentSummarizeParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentSummarizeParamsTest { +internal class ExperimentSummarizeParamsTest { @Test - fun createExperimentSummarizeParams() { + fun create() { ExperimentSummarizeParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .comparisonExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -18,27 +18,35 @@ class ExperimentSummarizeParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ExperimentSummarizeParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .comparisonExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .summarizeScores(true) .build() - val expected = mutableMapOf>() - expected.put("comparison_experiment_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("summarize_scores", listOf("true")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("comparison_experiment_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("summarize_scores", "true") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ExperimentSummarizeParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentTest.kt index 7ab7dcdc..534b2774 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentTest.kt @@ -2,11 +2,12 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentTest { +internal class ExperimentTest { @Test fun createExperiment() { @@ -23,7 +24,11 @@ class ExperimentTest { .datasetVersion("dataset_version") .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .description("description") - .metadata(Experiment.Metadata.builder().build()) + .metadata( + Experiment.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .repoInfo( RepoInfo.builder() .authorEmail("author_email") @@ -52,7 +57,12 @@ class ExperimentTest { assertThat(experiment.deletedAt()) .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(experiment.description()).contains("description") - assertThat(experiment.metadata()).contains(Experiment.Metadata.builder().build()) + assertThat(experiment.metadata()) + .contains( + Experiment.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(experiment.repoInfo()) .contains( RepoInfo.builder() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentUpdateParamsTest.kt index 22231f89..2284d934 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ExperimentUpdateParamsTest.kt @@ -2,21 +2,26 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ExperimentUpdateParamsTest { +internal class ExperimentUpdateParamsTest { @Test - fun createExperimentUpdateParams() { + fun create() { ExperimentUpdateParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .baseExpId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .datasetVersion("dataset_version") .description("description") - .metadata(ExperimentUpdateParams.Metadata.builder().build()) + .metadata( + ExperimentUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .public_(true) .repoInfo( @@ -36,7 +41,7 @@ class ExperimentUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = ExperimentUpdateParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -44,7 +49,11 @@ class ExperimentUpdateParamsTest { .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .datasetVersion("dataset_version") .description("description") - .metadata(ExperimentUpdateParams.Metadata.builder().build()) + .metadata( + ExperimentUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .public_(true) .repoInfo( @@ -61,17 +70,24 @@ class ExperimentUpdateParamsTest { .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.baseExpId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.datasetId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.datasetVersion()).isEqualTo("dataset_version") - assertThat(body.description()).isEqualTo("description") - assertThat(body.metadata()).isEqualTo(ExperimentUpdateParams.Metadata.builder().build()) - assertThat(body.name()).isEqualTo("name") - assertThat(body.public_()).isEqualTo(true) + + val body = params._body() + + assertNotNull(body) + assertThat(body.baseExpId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.datasetId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.datasetVersion()).contains("dataset_version") + assertThat(body.description()).contains("description") + assertThat(body.metadata()) + .contains( + ExperimentUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.name()).contains("name") + assertThat(body.public_()).contains(true) assertThat(body.repoInfo()) - .isEqualTo( + .contains( RepoInfo.builder() .authorEmail("author_email") .authorName("author_name") @@ -87,13 +103,15 @@ class ExperimentUpdateParamsTest { } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ExperimentUpdateParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackDatasetItemTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackDatasetItemTest.kt index 76dd0db6..b10a7fce 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackDatasetItemTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackDatasetItemTest.kt @@ -2,10 +2,11 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FeedbackDatasetItemTest { +internal class FeedbackDatasetItemTest { @Test fun createFeedbackDatasetItem() { @@ -13,14 +14,24 @@ class FeedbackDatasetItemTest { FeedbackDatasetItem.builder() .id("id") .comment("comment") - .metadata(FeedbackDatasetItem.Metadata.builder().build()) + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .source(FeedbackDatasetItem.Source.APP) + .addTag("string") .build() assertThat(feedbackDatasetItem).isNotNull assertThat(feedbackDatasetItem.id()).isEqualTo("id") assertThat(feedbackDatasetItem.comment()).contains("comment") assertThat(feedbackDatasetItem.metadata()) - .contains(FeedbackDatasetItem.Metadata.builder().build()) + .contains( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(feedbackDatasetItem.source()).contains(FeedbackDatasetItem.Source.APP) + assertThat(feedbackDatasetItem.tags().get()).containsExactly("string") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackExperimentItemTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackExperimentItemTest.kt index 35ee660b..2b36a2b7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackExperimentItemTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackExperimentItemTest.kt @@ -2,11 +2,11 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FeedbackExperimentItemTest { +internal class FeedbackExperimentItemTest { @Test fun createFeedbackExperimentItem() { @@ -14,19 +14,38 @@ class FeedbackExperimentItemTest { FeedbackExperimentItem.builder() .id("id") .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackExperimentItem.Metadata.builder().build()) - .scores(FeedbackExperimentItem.Scores.builder().build()) + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .source(FeedbackExperimentItem.Source.APP) + .addTag("string") .build() assertThat(feedbackExperimentItem).isNotNull assertThat(feedbackExperimentItem.id()).isEqualTo("id") assertThat(feedbackExperimentItem.comment()).contains("comment") - assertThat(feedbackExperimentItem._expected()).isEqualTo(JsonNull.of()) + assertThat(feedbackExperimentItem._expected()) + .isEqualTo(JsonValue.from(mapOf())) assertThat(feedbackExperimentItem.metadata()) - .contains(FeedbackExperimentItem.Metadata.builder().build()) + .contains( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(feedbackExperimentItem.scores()) - .contains(FeedbackExperimentItem.Scores.builder().build()) + .contains( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) assertThat(feedbackExperimentItem.source()).contains(FeedbackExperimentItem.Source.APP) + assertThat(feedbackExperimentItem.tags().get()).containsExactly("string") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItemTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItemTest.kt index 3f219e5d..6fea45de 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItemTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackProjectLogsItemTest.kt @@ -2,11 +2,11 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FeedbackProjectLogsItemTest { +internal class FeedbackProjectLogsItemTest { @Test fun createFeedbackProjectLogsItem() { @@ -14,19 +14,38 @@ class FeedbackProjectLogsItemTest { FeedbackProjectLogsItem.builder() .id("id") .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackProjectLogsItem.Metadata.builder().build()) - .scores(FeedbackProjectLogsItem.Scores.builder().build()) + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") .build() assertThat(feedbackProjectLogsItem).isNotNull assertThat(feedbackProjectLogsItem.id()).isEqualTo("id") assertThat(feedbackProjectLogsItem.comment()).contains("comment") - assertThat(feedbackProjectLogsItem._expected()).isEqualTo(JsonNull.of()) + assertThat(feedbackProjectLogsItem._expected()) + .isEqualTo(JsonValue.from(mapOf())) assertThat(feedbackProjectLogsItem.metadata()) - .contains(FeedbackProjectLogsItem.Metadata.builder().build()) + .contains( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(feedbackProjectLogsItem.scores()) - .contains(FeedbackProjectLogsItem.Scores.builder().build()) + .contains( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) assertThat(feedbackProjectLogsItem.source()).contains(FeedbackProjectLogsItem.Source.APP) + assertThat(feedbackProjectLogsItem.tags().get()).containsExactly("string") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackResponseSchemaTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackResponseSchemaTest.kt index a1b62a0b..bafdb30c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackResponseSchemaTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FeedbackResponseSchemaTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FeedbackResponseSchemaTest { +internal class FeedbackResponseSchemaTest { @Test fun createFeedbackResponseSchema() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponseTest.kt index 220705b1..ced9effd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchDatasetEventsResponseTest.kt @@ -2,33 +2,41 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FetchDatasetEventsResponseTest { +internal class FetchDatasetEventsResponseTest { @Test fun createFetchDatasetEventsResponse() { val fetchDatasetEventsResponse = FetchDatasetEventsResponse.builder() - .events( - listOf( - DatasetEvent.builder() - .id("id") - ._xactId("_xact_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .rootSpanId("root_span_id") - .spanId("span_id") - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(DatasetEvent.Metadata.builder().build()) - .tags(listOf("string")) - .build() - ) + .addEvent( + DatasetEvent.builder() + .id("id") + ._xactId("_xact_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .rootSpanId("root_span_id") + .spanId("span_id") + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(DatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .addTag("string") + .build() ) .cursor("cursor") .build() @@ -43,10 +51,20 @@ class FetchDatasetEventsResponseTest { .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .rootSpanId("root_span_id") .spanId("span_id") - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(DatasetEvent.Metadata.builder().build()) - .tags(listOf("string")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(DatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .addTag("string") .build() ) assertThat(fetchDatasetEventsResponse.cursor()).contains("cursor") diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponseTest.kt index 3674eabf..7ec8e63b 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchExperimentEventsResponseTest.kt @@ -2,60 +2,71 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FetchExperimentEventsResponseTest { +internal class FetchExperimentEventsResponseTest { @Test fun createFetchExperimentEventsResponse() { val fetchExperimentEventsResponse = FetchExperimentEventsResponse.builder() - .events( - listOf( - ExperimentEvent.builder() - .id("id") - ._xactId("_xact_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .rootSpanId("root_span_id") - .spanId("span_id") - .context( - ExperimentEvent.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ExperimentEvent.Metadata.builder().build()) - .metrics( - ExperimentEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(ExperimentEvent.Scores.builder().build()) - .spanAttributes( - ExperimentEvent.SpanAttributes.builder() - .name("name") - .type(ExperimentEvent.SpanAttributes.Type.LLM) - .build() - ) - .spanParents(listOf("string")) - .tags(listOf("string")) - .build() - ) + .addEvent( + ExperimentEvent.builder() + .id("id") + ._xactId("_xact_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .rootSpanId("root_span_id") + .spanId("span_id") + .context( + ExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ExperimentEvent.Metadata.builder().model("model").build()) + .metrics( + ExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .scores( + ExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .addSpanParent("string") + .addTag("string") + .build() ) .cursor("cursor") .build() @@ -74,33 +85,46 @@ class FetchExperimentEventsResponseTest { ExperimentEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ExperimentEvent.Metadata.builder().build()) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ExperimentEvent.Metadata.builder().model("model").build()) .metrics( ExperimentEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - .output(JsonNull.of()) - .scores(ExperimentEvent.Scores.builder().build()) - .spanAttributes( - ExperimentEvent.SpanAttributes.builder() - .name("name") - .type(ExperimentEvent.SpanAttributes.Type.LLM) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .scores( + ExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) .build() ) - .spanParents(listOf("string")) - .tags(listOf("string")) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .addSpanParent("string") + .addTag("string") .build() ) assertThat(fetchExperimentEventsResponse.cursor()).contains("cursor") diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponseTest.kt index c34a05b2..ae7b0b5a 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FetchProjectLogsEventsResponseTest.kt @@ -2,60 +2,72 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FetchProjectLogsEventsResponseTest { +internal class FetchProjectLogsEventsResponseTest { @Test fun createFetchProjectLogsEventsResponse() { val fetchProjectLogsEventsResponse = FetchProjectLogsEventsResponse.builder() - .events( - listOf( - ProjectLogsEvent.builder() - .id("id") - ._xactId("_xact_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .logId(ProjectLogsEvent.LogId.G) - .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .rootSpanId("root_span_id") - .spanId("span_id") - .context( - ProjectLogsEvent.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ProjectLogsEvent.Metadata.builder().build()) - .metrics( - ProjectLogsEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(ProjectLogsEvent.Scores.builder().build()) - .spanAttributes( - ProjectLogsEvent.SpanAttributes.builder() - .name("name") - .type(ProjectLogsEvent.SpanAttributes.Type.LLM) - .build() - ) - .spanParents(listOf("string")) - .tags(listOf("string")) - .build() - ) + .addEvent( + ProjectLogsEvent.builder() + .id("id") + ._xactId("_xact_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .logId(ProjectLogsEvent.LogId.G) + .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .rootSpanId("root_span_id") + .spanId("span_id") + .context( + ProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ProjectLogsEvent.Metadata.builder().model("model").build()) + .metrics( + ProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .scores( + ProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .addSpanParent("string") + .addTag("string") + .build() ) .cursor("cursor") .build() @@ -75,32 +87,46 @@ class FetchProjectLogsEventsResponseTest { ProjectLogsEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ProjectLogsEvent.Metadata.builder().build()) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ProjectLogsEvent.Metadata.builder().model("model").build()) .metrics( ProjectLogsEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - .output(JsonNull.of()) - .scores(ProjectLogsEvent.Scores.builder().build()) - .spanAttributes( - ProjectLogsEvent.SpanAttributes.builder() - .name("name") - .type(ProjectLogsEvent.SpanAttributes.Type.LLM) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .scores( + ProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) .build() ) - .spanParents(listOf("string")) - .tags(listOf("string")) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .addSpanParent("string") + .addTag("string") .build() ) assertThat(fetchProjectLogsEventsResponse.cursor()).contains("cursor") diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionCreateParamsTest.kt index c5cc94d4..a4747bcf 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionCreateParamsTest.kt @@ -2,81 +2,82 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionCreateParamsTest { +internal class FunctionCreateParamsTest { @Test - fun createFunctionCreateParams() { + fun create() { FunctionCreateParams.builder() .functionData( - FunctionCreateParams.FunctionData.ofPrompt( - FunctionCreateParams.FunctionData.Prompt.builder() - .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionCreateParams.FunctionData.Prompt.builder() + .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionCreateParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionCreateParams.FunctionType.LLM) .origin( FunctionCreateParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionCreateParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -90,105 +91,104 @@ class FunctionCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = FunctionCreateParams.builder() .functionData( - FunctionCreateParams.FunctionData.ofPrompt( - FunctionCreateParams.FunctionData.Prompt.builder() - .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionCreateParams.FunctionData.Prompt.builder() + .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionCreateParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionCreateParams.FunctionType.LLM) .origin( FunctionCreateParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionCreateParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -202,35 +202,35 @@ class FunctionCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.functionData()) .isEqualTo( FunctionCreateParams.FunctionData.ofPrompt( @@ -239,67 +239,70 @@ class FunctionCreateParamsTest { .build() ) ) - assertThat(body.name()).isEqualTo("name") + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") - assertThat(body.description()).isEqualTo("description") + assertThat(body.slug()).isEqualTo("x") + assertThat(body.description()).contains("description") assertThat(body.functionSchema()) - .isEqualTo( + .contains( FunctionCreateParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) - assertThat(body.functionType()).isEqualTo(FunctionCreateParams.FunctionType.LLM) + assertThat(body.functionType()).contains(FunctionCreateParams.FunctionType.LLM) assertThat(body.origin()) - .isEqualTo( + .contains( FunctionCreateParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionCreateParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -313,51 +316,49 @@ class FunctionCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = FunctionCreateParams.builder() .functionData( - FunctionCreateParams.FunctionData.ofPrompt( - FunctionCreateParams.FunctionData.Prompt.builder() - .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionCreateParams.FunctionData.Prompt.builder() + .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.functionData()) .isEqualTo( FunctionCreateParams.FunctionData.ofPrompt( @@ -366,8 +367,8 @@ class FunctionCreateParamsTest { .build() ) ) - assertThat(body.name()).isEqualTo("name") + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") + assertThat(body.slug()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionDeleteParamsTest.kt index b6a1f5f2..4b8a7c19 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionDeleteParamsTest { +internal class FunctionDeleteParamsTest { @Test - fun createFunctionDeleteParams() { + fun create() { FunctionDeleteParams.builder().functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionInvokeParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionInvokeParamsTest.kt index 8b261382..988dc6e4 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionInvokeParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionInvokeParamsTest.kt @@ -2,32 +2,78 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionInvokeParamsTest { +internal class FunctionInvokeParamsTest { @Test - fun createFunctionInvokeParams() { + fun create() { FunctionInvokeParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input(JsonNull.of()) - .messages( - listOf( - FunctionInvokeParams.Message.ofSystem( - FunctionInvokeParams.Message.System.builder() - .role(FunctionInvokeParams.Message.System.Role.SYSTEM) - .content("content") - .name("name") - .build() - ) - ) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .addMessage( + FunctionInvokeParams.Message.System.builder() + .role(FunctionInvokeParams.Message.System.Role.SYSTEM) + .content("content") + .name("name") + .build() + ) + .metadata( + FunctionInvokeParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() ) .mode(FunctionInvokeParams.Mode.AUTO) .parent( - FunctionInvokeParams.Parent.ofSpanParentStruct( + FunctionInvokeParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + FunctionInvokeParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + FunctionInvokeParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .stream(true) + .version("version") + .build() + } + + @Test + fun body() { + val params = + FunctionInvokeParams.builder() + .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .addMessage( + FunctionInvokeParams.Message.System.builder() + .role(FunctionInvokeParams.Message.System.Role.SYSTEM) + .content("content") + .name("name") + .build() + ) + .metadata( + FunctionInvokeParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .mode(FunctionInvokeParams.Mode.AUTO) + .parent( FunctionInvokeParams.Parent.SpanParentStruct.builder() .objectId("object_id") .objectType( @@ -35,6 +81,7 @@ class FunctionInvokeParamsTest { ) .propagatedEvent( FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .rowIds( @@ -46,60 +93,17 @@ class FunctionInvokeParamsTest { ) .build() ) - ) - .stream(true) - .version("version") - .build() - } - - @Test - fun getBody() { - val params = - FunctionInvokeParams.builder() - .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input(JsonNull.of()) - .messages( - listOf( - FunctionInvokeParams.Message.ofSystem( - FunctionInvokeParams.Message.System.builder() - .role(FunctionInvokeParams.Message.System.Role.SYSTEM) - .content("content") - .name("name") - .build() - ) - ) - ) - .mode(FunctionInvokeParams.Mode.AUTO) - .parent( - FunctionInvokeParams.Parent.ofSpanParentStruct( - FunctionInvokeParams.Parent.SpanParentStruct.builder() - .objectId("object_id") - .objectType( - FunctionInvokeParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS - ) - .propagatedEvent( - FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent - .builder() - .build() - ) - .rowIds( - FunctionInvokeParams.Parent.SpanParentStruct.RowIds.builder() - .id("id") - .rootSpanId("root_span_id") - .spanId("span_id") - .build() - ) - .build() - ) - ) .stream(true) .version("version") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.input()).isEqualTo(JsonNull.of()) + + val body = params._body() + + assertNotNull(body) + assertThat(body._expected()).isEqualTo(JsonValue.from(mapOf())) + assertThat(body._input()).isEqualTo(JsonValue.from(mapOf())) assertThat(body.messages()) - .isEqualTo( + .contains( listOf( FunctionInvokeParams.Message.ofSystem( FunctionInvokeParams.Message.System.builder() @@ -110,9 +114,15 @@ class FunctionInvokeParamsTest { ) ) ) - assertThat(body.mode()).isEqualTo(FunctionInvokeParams.Mode.AUTO) + assertThat(body.metadata()) + .contains( + FunctionInvokeParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + assertThat(body.mode()).contains(FunctionInvokeParams.Mode.AUTO) assertThat(body.parent()) - .isEqualTo( + .contains( FunctionInvokeParams.Parent.ofSpanParentStruct( FunctionInvokeParams.Parent.SpanParentStruct.builder() .objectId("object_id") @@ -121,6 +131,7 @@ class FunctionInvokeParamsTest { ) .propagatedEvent( FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) .rowIds( @@ -133,18 +144,20 @@ class FunctionInvokeParamsTest { .build() ) ) - assertThat(body.stream()).isEqualTo(true) - assertThat(body.version()).isEqualTo("version") + assertThat(body.stream()).contains(true) + assertThat(body.version()).contains("version") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = FunctionInvokeParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionListParamsTest.kt index 5e560da4..00e37ef9 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionListParamsTest.kt @@ -2,19 +2,19 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionListParamsTest { +internal class FunctionListParamsTest { @Test - fun createFunctionListParams() { + fun create() { FunctionListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .functionName("function_name") - .ids(FunctionListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -25,13 +25,13 @@ class FunctionListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = FunctionListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .functionName("function_name") - .ids(FunctionListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -39,29 +39,32 @@ class FunctionListParamsTest { .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .version("version") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("function_name", listOf("function_name")) - expected.put( - "ids", - listOf( - FunctionListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("function_name", "function_name") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("slug", "slug") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("version", "version") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("slug", listOf("slug")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("version", listOf("version")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = FunctionListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionReplaceParamsTest.kt index 3afb5a00..a1c6af81 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionReplaceParamsTest.kt @@ -2,81 +2,82 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionReplaceParamsTest { +internal class FunctionReplaceParamsTest { @Test - fun createFunctionReplaceParams() { + fun create() { FunctionReplaceParams.builder() .functionData( - FunctionReplaceParams.FunctionData.ofPrompt( - FunctionReplaceParams.FunctionData.Prompt.builder() - .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionReplaceParams.FunctionData.Prompt.builder() + .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionReplaceParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionReplaceParams.FunctionType.LLM) .origin( FunctionReplaceParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionReplaceParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -90,105 +91,104 @@ class FunctionReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = FunctionReplaceParams.builder() .functionData( - FunctionReplaceParams.FunctionData.ofPrompt( - FunctionReplaceParams.FunctionData.Prompt.builder() - .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionReplaceParams.FunctionData.Prompt.builder() + .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionReplaceParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionReplaceParams.FunctionType.LLM) .origin( FunctionReplaceParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionReplaceParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -202,35 +202,35 @@ class FunctionReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.functionData()) .isEqualTo( FunctionReplaceParams.FunctionData.ofPrompt( @@ -239,67 +239,70 @@ class FunctionReplaceParamsTest { .build() ) ) - assertThat(body.name()).isEqualTo("name") + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") - assertThat(body.description()).isEqualTo("description") + assertThat(body.slug()).isEqualTo("x") + assertThat(body.description()).contains("description") assertThat(body.functionSchema()) - .isEqualTo( + .contains( FunctionReplaceParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) - assertThat(body.functionType()).isEqualTo(FunctionReplaceParams.FunctionType.LLM) + assertThat(body.functionType()).contains(FunctionReplaceParams.FunctionType.LLM) assertThat(body.origin()) - .isEqualTo( + .contains( FunctionReplaceParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionReplaceParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -313,51 +316,49 @@ class FunctionReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = FunctionReplaceParams.builder() .functionData( - FunctionReplaceParams.FunctionData.ofPrompt( - FunctionReplaceParams.FunctionData.Prompt.builder() - .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionReplaceParams.FunctionData.Prompt.builder() + .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.functionData()) .isEqualTo( FunctionReplaceParams.FunctionData.ofPrompt( @@ -366,8 +367,8 @@ class FunctionReplaceParamsTest { .build() ) ) - assertThat(body.name()).isEqualTo("name") + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") + assertThat(body.slug()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionRetrieveParamsTest.kt index e67f96c5..9890c9f3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionRetrieveParamsTest { +internal class FunctionRetrieveParamsTest { @Test - fun createFunctionRetrieveParams() { + fun create() { FunctionRetrieveParams.builder().functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionTest.kt index 566aec42..b42ee0e0 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionTest.kt @@ -2,12 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionTest { +internal class FunctionTest { @Test fun createFunction() { @@ -16,11 +16,9 @@ class FunctionTest { .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") ._xactId("_xact_id") .functionData( - Function.FunctionData.ofPrompt( - Function.FunctionData.Prompt.builder() - .type(Function.FunctionData.Prompt.Type.PROMPT) - .build() - ) + Function.FunctionData.Prompt.builder() + .type(Function.FunctionData.Prompt.Type.PROMPT) + .build() ) .logId(Function.LogId.P) .name("name") @@ -31,60 +29,67 @@ class FunctionTest { .description("description") .functionSchema( Function.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(Function.FunctionType.LLM) - .metadata(Function.Metadata.builder().build()) + .metadata( + Function.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .origin( Function.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Function.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -98,32 +103,30 @@ class FunctionTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() assertThat(function).isNotNull assertThat(function.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -146,17 +149,22 @@ class FunctionTest { assertThat(function.functionSchema()) .contains( Function.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) assertThat(function.functionType()).contains(Function.FunctionType.LLM) - assertThat(function.metadata()).contains(Function.Metadata.builder().build()) + assertThat(function.metadata()) + .contains( + Function.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(function.origin()) .contains( Function.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(Function.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) @@ -164,43 +172,46 @@ class FunctionTest { .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -214,28 +225,26 @@ class FunctionTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionToolChoiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionToolChoiceTest.kt deleted file mode 100644 index 6321b346..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionToolChoiceTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class FunctionToolChoiceTest { - - @Test - fun createFunctionToolChoice() { - val functionToolChoice = FunctionToolChoice.builder().name("name").build() - assertThat(functionToolChoice).isNotNull - assertThat(functionToolChoice.name()).isEqualTo("name") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionUpdateParamsTest.kt index e5763185..261982cd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/FunctionUpdateParamsTest.kt @@ -2,65 +2,67 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class FunctionUpdateParamsTest { +internal class FunctionUpdateParamsTest { @Test - fun createFunctionUpdateParams() { + fun create() { FunctionUpdateParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") .functionData( - FunctionUpdateParams.FunctionData.ofPrompt( - FunctionUpdateParams.FunctionData.Prompt.builder() - .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionUpdateParams.FunctionData.Prompt.builder() + .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) .name("name") .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -74,90 +76,89 @@ class FunctionUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = FunctionUpdateParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") .functionData( - FunctionUpdateParams.FunctionData.ofPrompt( - FunctionUpdateParams.FunctionData.Prompt.builder() - .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionUpdateParams.FunctionData.Prompt.builder() + .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) .name("name") .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -171,86 +172,89 @@ class FunctionUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.description()).isEqualTo("description") + + val body = params._body() + + assertNotNull(body) + assertThat(body.description()).contains("description") assertThat(body.functionData()) - .isEqualTo( + .contains( FunctionUpdateParams.FunctionData.ofPrompt( FunctionUpdateParams.FunctionData.Prompt.builder() .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) .build() ) ) - assertThat(body.name()).isEqualTo("name") + assertThat(body.name()).contains("name") assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -264,42 +268,42 @@ class FunctionUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = FunctionUpdateParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupCreateParamsTest.kt index b7b98eb3..4707e762 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupCreateParamsTest.kt @@ -2,47 +2,51 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupCreateParamsTest { +internal class GroupCreateParamsTest { @Test - fun createGroupCreateParams() { + fun create() { GroupCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() } @Test - fun getBody() { + fun body() { val params = GroupCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") - assertThat(body.description()).isEqualTo("description") - assertThat(body.memberGroups()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.memberUsers()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.orgName()).isEqualTo("org_name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") + assertThat(body.description()).contains("description") + assertThat(body.memberGroups()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.memberUsers()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { - val params = GroupCreateParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + fun bodyWithoutOptionalFields() { + val params = GroupCreateParams.builder().name("x").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupDeleteParamsTest.kt index dd8a03f2..362fe3f6 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupDeleteParamsTest { +internal class GroupDeleteParamsTest { @Test - fun createGroupDeleteParams() { + fun create() { GroupDeleteParams.builder().groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupListParamsTest.kt index 33587c15..17892a31 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupListParamsTest.kt @@ -2,52 +2,57 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupListParamsTest { +internal class GroupListParamsTest { @Test - fun createGroupListParams() { + fun create() { GroupListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .ids(GroupListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = GroupListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .ids(GroupListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("group_name", listOf("group_name")) - expected.put( - "ids", - listOf(GroupListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("group_name", "group_name") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = GroupListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupReplaceParamsTest.kt index 4bc2570a..d5c3f0ec 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupReplaceParamsTest.kt @@ -2,47 +2,51 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupReplaceParamsTest { +internal class GroupReplaceParamsTest { @Test - fun createGroupReplaceParams() { + fun create() { GroupReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() } @Test - fun getBody() { + fun body() { val params = GroupReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") - assertThat(body.description()).isEqualTo("description") - assertThat(body.memberGroups()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.memberUsers()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.orgName()).isEqualTo("org_name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") + assertThat(body.description()).contains("description") + assertThat(body.memberGroups()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.memberUsers()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { - val params = GroupReplaceParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + fun bodyWithoutOptionalFields() { + val params = GroupReplaceParams.builder().name("x").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupRetrieveParamsTest.kt index 40cb190f..ea355d6a 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupRetrieveParamsTest { +internal class GroupRetrieveParamsTest { @Test - fun createGroupRetrieveParams() { + fun create() { GroupRetrieveParams.builder().groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupTest.kt index 4b8a9f64..235fb2a1 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupTest { +internal class GroupTest { @Test fun createGroup() { @@ -18,8 +18,8 @@ class GroupTest { .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() assertThat(group).isNotNull diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupUpdateParamsTest.kt index f84d7191..ece1b27d 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/GroupUpdateParamsTest.kt @@ -2,55 +2,59 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class GroupUpdateParamsTest { +internal class GroupUpdateParamsTest { @Test - fun createGroupUpdateParams() { + fun create() { GroupUpdateParams.builder() .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .addMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .removeMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .name("x") + .addRemoveMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addRemoveMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getBody() { + fun body() { val params = GroupUpdateParams.builder() .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .addMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .removeMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .name("x") + .addRemoveMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addRemoveMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.addMemberGroups()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.addMemberUsers()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.description()).isEqualTo("description") - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.addMemberGroups()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.addMemberUsers()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("x") assertThat(body.removeMemberGroups()) - .isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) assertThat(body.removeMemberUsers()) - .isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = GroupUpdateParams.builder().groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventMergeTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventMergeTest.kt deleted file mode 100755 index b90e611f..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventMergeTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertDatasetEventMergeTest { - - @Test - fun createInsertDatasetEventMerge() { - val insertDatasetEventMerge = - InsertDatasetEventMerge.builder() - ._isMerge(true) - .id("id") - ._mergePaths(listOf(listOf("string"))) - ._objectDelete(true) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventMerge.Metadata.builder().build()) - .tags(listOf("string")) - .build() - assertThat(insertDatasetEventMerge).isNotNull - assertThat(insertDatasetEventMerge._isMerge()).isEqualTo(true) - assertThat(insertDatasetEventMerge.id()).contains("id") - assertThat(insertDatasetEventMerge._mergePaths().get()).containsExactly(listOf("string")) - assertThat(insertDatasetEventMerge._objectDelete()).contains(true) - assertThat(insertDatasetEventMerge.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertDatasetEventMerge._expected()).isEqualTo(JsonNull.of()) - assertThat(insertDatasetEventMerge._input()).isEqualTo(JsonNull.of()) - assertThat(insertDatasetEventMerge.metadata()) - .contains(InsertDatasetEventMerge.Metadata.builder().build()) - assertThat(insertDatasetEventMerge.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplaceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplaceTest.kt deleted file mode 100755 index 55e6cf57..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventReplaceTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertDatasetEventReplaceTest { - - @Test - fun createInsertDatasetEventReplace() { - val insertDatasetEventReplace = - InsertDatasetEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventReplace.Metadata.builder().build()) - .tags(listOf("string")) - .build() - assertThat(insertDatasetEventReplace).isNotNull - assertThat(insertDatasetEventReplace.id()).contains("id") - assertThat(insertDatasetEventReplace._isMerge()).contains(true) - assertThat(insertDatasetEventReplace._objectDelete()).contains(true) - assertThat(insertDatasetEventReplace._parentId()).contains("_parent_id") - assertThat(insertDatasetEventReplace.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertDatasetEventReplace._expected()).isEqualTo(JsonNull.of()) - assertThat(insertDatasetEventReplace._input()).isEqualTo(JsonNull.of()) - assertThat(insertDatasetEventReplace.metadata()) - .contains(InsertDatasetEventReplace.Metadata.builder().build()) - assertThat(insertDatasetEventReplace.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventTest.kt new file mode 100644 index 00000000..176a9e81 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertDatasetEventTest.kt @@ -0,0 +1,66 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.JsonValue +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InsertDatasetEventTest { + + @Test + fun createInsertDatasetEvent() { + val insertDatasetEvent = + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + assertThat(insertDatasetEvent).isNotNull + assertThat(insertDatasetEvent.id()).contains("id") + assertThat(insertDatasetEvent._isMerge()).contains(true) + assertThat(insertDatasetEvent._mergePaths().get()).containsExactly(listOf("string")) + assertThat(insertDatasetEvent._objectDelete()).contains(true) + assertThat(insertDatasetEvent._parentId()).contains("_parent_id") + assertThat(insertDatasetEvent.created()) + .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(insertDatasetEvent._expected()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertDatasetEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertDatasetEvent.metadata()) + .contains(InsertDatasetEvent.Metadata.builder().model("model").build()) + assertThat(insertDatasetEvent.origin()) + .contains( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + assertThat(insertDatasetEvent.rootSpanId()).contains("root_span_id") + assertThat(insertDatasetEvent.spanId()).contains("span_id") + assertThat(insertDatasetEvent.spanParents().get()).containsExactly("string") + assertThat(insertDatasetEvent.tags().get()).containsExactly("string") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertEventsResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertEventsResponseTest.kt index a55a1208..bc8f0a96 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertEventsResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertEventsResponseTest.kt @@ -5,11 +5,11 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class InsertEventsResponseTest { +internal class InsertEventsResponseTest { @Test fun createInsertEventsResponse() { - val insertEventsResponse = InsertEventsResponse.builder().rowIds(listOf("string")).build() + val insertEventsResponse = InsertEventsResponse.builder().addRowId("string").build() assertThat(insertEventsResponse).isNotNull assertThat(insertEventsResponse.rowIds()).containsExactly("string") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventMergeTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventMergeTest.kt deleted file mode 100755 index 59aee6e3..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventMergeTest.kt +++ /dev/null @@ -1,95 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertExperimentEventMergeTest { - - @Test - fun createInsertExperimentEventMerge() { - val insertExperimentEventMerge = - InsertExperimentEventMerge.builder() - ._isMerge(true) - .id("id") - ._mergePaths(listOf(listOf("string"))) - ._objectDelete(true) - .context( - InsertExperimentEventMerge.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertExperimentEventMerge.Metadata.builder().build()) - .metrics( - InsertExperimentEventMerge.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventMerge.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventMerge.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventMerge.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - assertThat(insertExperimentEventMerge).isNotNull - assertThat(insertExperimentEventMerge._isMerge()).isEqualTo(true) - assertThat(insertExperimentEventMerge.id()).contains("id") - assertThat(insertExperimentEventMerge._mergePaths().get()).containsExactly(listOf("string")) - assertThat(insertExperimentEventMerge._objectDelete()).contains(true) - assertThat(insertExperimentEventMerge.context()) - .contains( - InsertExperimentEventMerge.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - assertThat(insertExperimentEventMerge.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertExperimentEventMerge.datasetRecordId()).contains("dataset_record_id") - assertThat(insertExperimentEventMerge._error()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventMerge._expected()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventMerge._input()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventMerge.metadata()) - .contains(InsertExperimentEventMerge.Metadata.builder().build()) - assertThat(insertExperimentEventMerge.metrics()) - .contains( - InsertExperimentEventMerge.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - assertThat(insertExperimentEventMerge._output()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventMerge.scores()) - .contains(InsertExperimentEventMerge.Scores.builder().build()) - assertThat(insertExperimentEventMerge.spanAttributes()) - .contains( - InsertExperimentEventMerge.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventMerge.SpanAttributes.Type.LLM) - .build() - ) - assertThat(insertExperimentEventMerge.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplaceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplaceTest.kt deleted file mode 100755 index 0de4d47c..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventReplaceTest.kt +++ /dev/null @@ -1,95 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertExperimentEventReplaceTest { - - @Test - fun createInsertExperimentEventReplace() { - val insertExperimentEventReplace = - InsertExperimentEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertExperimentEventReplace.Metadata.builder().build()) - .metrics( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventReplace.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - assertThat(insertExperimentEventReplace).isNotNull - assertThat(insertExperimentEventReplace.id()).contains("id") - assertThat(insertExperimentEventReplace._isMerge()).contains(true) - assertThat(insertExperimentEventReplace._objectDelete()).contains(true) - assertThat(insertExperimentEventReplace._parentId()).contains("_parent_id") - assertThat(insertExperimentEventReplace.context()) - .contains( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - assertThat(insertExperimentEventReplace.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertExperimentEventReplace.datasetRecordId()).contains("dataset_record_id") - assertThat(insertExperimentEventReplace._error()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventReplace._expected()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventReplace._input()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventReplace.metadata()) - .contains(InsertExperimentEventReplace.Metadata.builder().build()) - assertThat(insertExperimentEventReplace.metrics()) - .contains( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - assertThat(insertExperimentEventReplace._output()).isEqualTo(JsonNull.of()) - assertThat(insertExperimentEventReplace.scores()) - .contains(InsertExperimentEventReplace.Scores.builder().build()) - assertThat(insertExperimentEventReplace.spanAttributes()) - .contains( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertExperimentEventReplace.SpanAttributes.Type.LLM) - .build() - ) - assertThat(insertExperimentEventReplace.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventTest.kt new file mode 100644 index 00000000..3f52dc7f --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertExperimentEventTest.kt @@ -0,0 +1,125 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.JsonValue +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InsertExperimentEventTest { + + @Test + fun createInsertExperimentEvent() { + val insertExperimentEvent = + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertExperimentEvent.Metadata.builder().model("model").build()) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + assertThat(insertExperimentEvent).isNotNull + assertThat(insertExperimentEvent.id()).contains("id") + assertThat(insertExperimentEvent._isMerge()).contains(true) + assertThat(insertExperimentEvent._mergePaths().get()).containsExactly(listOf("string")) + assertThat(insertExperimentEvent._objectDelete()).contains(true) + assertThat(insertExperimentEvent._parentId()).contains("_parent_id") + assertThat(insertExperimentEvent.context()) + .contains( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + assertThat(insertExperimentEvent.created()) + .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(insertExperimentEvent._error()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertExperimentEvent._expected()) + .isEqualTo(JsonValue.from(mapOf())) + assertThat(insertExperimentEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertExperimentEvent.metadata()) + .contains(InsertExperimentEvent.Metadata.builder().model("model").build()) + assertThat(insertExperimentEvent.metrics()) + .contains( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + assertThat(insertExperimentEvent.origin()) + .contains( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + assertThat(insertExperimentEvent._output()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertExperimentEvent.rootSpanId()).contains("root_span_id") + assertThat(insertExperimentEvent.scores()) + .contains( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + assertThat(insertExperimentEvent.spanAttributes()) + .contains(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + assertThat(insertExperimentEvent.spanId()).contains("span_id") + assertThat(insertExperimentEvent.spanParents().get()).containsExactly("string") + assertThat(insertExperimentEvent.tags().get()).containsExactly("string") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMergeTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMergeTest.kt deleted file mode 100755 index 64e559b8..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventMergeTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertProjectLogsEventMergeTest { - - @Test - fun createInsertProjectLogsEventMerge() { - val insertProjectLogsEventMerge = - InsertProjectLogsEventMerge.builder() - ._isMerge(true) - .id("id") - ._mergePaths(listOf(listOf("string"))) - ._objectDelete(true) - .context( - InsertProjectLogsEventMerge.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertProjectLogsEventMerge.Metadata.builder().build()) - .metrics( - InsertProjectLogsEventMerge.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventMerge.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventMerge.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventMerge.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - assertThat(insertProjectLogsEventMerge).isNotNull - assertThat(insertProjectLogsEventMerge._isMerge()).isEqualTo(true) - assertThat(insertProjectLogsEventMerge.id()).contains("id") - assertThat(insertProjectLogsEventMerge._mergePaths().get()) - .containsExactly(listOf("string")) - assertThat(insertProjectLogsEventMerge._objectDelete()).contains(true) - assertThat(insertProjectLogsEventMerge.context()) - .contains( - InsertProjectLogsEventMerge.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - assertThat(insertProjectLogsEventMerge.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertProjectLogsEventMerge._error()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventMerge._expected()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventMerge._input()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventMerge.metadata()) - .contains(InsertProjectLogsEventMerge.Metadata.builder().build()) - assertThat(insertProjectLogsEventMerge.metrics()) - .contains( - InsertProjectLogsEventMerge.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - assertThat(insertProjectLogsEventMerge._output()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventMerge.scores()) - .contains(InsertProjectLogsEventMerge.Scores.builder().build()) - assertThat(insertProjectLogsEventMerge.spanAttributes()) - .contains( - InsertProjectLogsEventMerge.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventMerge.SpanAttributes.Type.LLM) - .build() - ) - assertThat(insertProjectLogsEventMerge.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplaceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplaceTest.kt deleted file mode 100755 index be86dc18..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventReplaceTest.kt +++ /dev/null @@ -1,93 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import java.time.OffsetDateTime -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class InsertProjectLogsEventReplaceTest { - - @Test - fun createInsertProjectLogsEventReplace() { - val insertProjectLogsEventReplace = - InsertProjectLogsEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertProjectLogsEventReplace.Metadata.builder().build()) - .metrics( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventReplace.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - assertThat(insertProjectLogsEventReplace).isNotNull - assertThat(insertProjectLogsEventReplace.id()).contains("id") - assertThat(insertProjectLogsEventReplace._isMerge()).contains(true) - assertThat(insertProjectLogsEventReplace._objectDelete()).contains(true) - assertThat(insertProjectLogsEventReplace._parentId()).contains("_parent_id") - assertThat(insertProjectLogsEventReplace.context()) - .contains( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - assertThat(insertProjectLogsEventReplace.created()) - .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(insertProjectLogsEventReplace._error()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventReplace._expected()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventReplace._input()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventReplace.metadata()) - .contains(InsertProjectLogsEventReplace.Metadata.builder().build()) - assertThat(insertProjectLogsEventReplace.metrics()) - .contains( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - assertThat(insertProjectLogsEventReplace._output()).isEqualTo(JsonNull.of()) - assertThat(insertProjectLogsEventReplace.scores()) - .contains(InsertProjectLogsEventReplace.Scores.builder().build()) - assertThat(insertProjectLogsEventReplace.spanAttributes()) - .contains( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventReplace.SpanAttributes.Type.LLM) - .build() - ) - assertThat(insertProjectLogsEventReplace.tags().get()).containsExactly("string") - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventTest.kt new file mode 100644 index 00000000..b3812878 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/InsertProjectLogsEventTest.kt @@ -0,0 +1,125 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.JsonValue +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InsertProjectLogsEventTest { + + @Test + fun createInsertProjectLogsEvent() { + val insertProjectLogsEvent = + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertProjectLogsEvent.Metadata.builder().model("model").build()) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + assertThat(insertProjectLogsEvent).isNotNull + assertThat(insertProjectLogsEvent.id()).contains("id") + assertThat(insertProjectLogsEvent._isMerge()).contains(true) + assertThat(insertProjectLogsEvent._mergePaths().get()).containsExactly(listOf("string")) + assertThat(insertProjectLogsEvent._objectDelete()).contains(true) + assertThat(insertProjectLogsEvent._parentId()).contains("_parent_id") + assertThat(insertProjectLogsEvent.context()) + .contains( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + assertThat(insertProjectLogsEvent.created()) + .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(insertProjectLogsEvent._error()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertProjectLogsEvent._expected()) + .isEqualTo(JsonValue.from(mapOf())) + assertThat(insertProjectLogsEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertProjectLogsEvent.metadata()) + .contains(InsertProjectLogsEvent.Metadata.builder().model("model").build()) + assertThat(insertProjectLogsEvent.metrics()) + .contains( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + assertThat(insertProjectLogsEvent.origin()) + .contains( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + assertThat(insertProjectLogsEvent._output()).isEqualTo(JsonValue.from(mapOf())) + assertThat(insertProjectLogsEvent.rootSpanId()).contains("root_span_id") + assertThat(insertProjectLogsEvent.scores()) + .contains( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + assertThat(insertProjectLogsEvent.spanAttributes()) + .contains(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + assertThat(insertProjectLogsEvent.spanId()).contains("span_id") + assertThat(insertProjectLogsEvent.spanParents().get()).containsExactly("string") + assertThat(insertProjectLogsEvent.tags().get()).containsExactly("string") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/MetricSummaryTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/MetricSummaryTest.kt index 50e74b12..a1dc0294 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/MetricSummaryTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/MetricSummaryTest.kt @@ -5,25 +5,25 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class MetricSummaryTest { +internal class MetricSummaryTest { @Test fun createMetricSummary() { val metricSummary = MetricSummary.builder() - .improvements(123L) - .metric(42.23) + .improvements(0L) + .metric(0.0) .name("name") - .regressions(123L) + .regressions(0L) .unit("unit") - .diff(42.23) + .diff(0.0) .build() assertThat(metricSummary).isNotNull - assertThat(metricSummary.improvements()).isEqualTo(123L) - assertThat(metricSummary.metric()).isEqualTo(42.23) + assertThat(metricSummary.improvements()).isEqualTo(0L) + assertThat(metricSummary.metric()).isEqualTo(0.0) assertThat(metricSummary.name()).isEqualTo("name") - assertThat(metricSummary.regressions()).isEqualTo(123L) + assertThat(metricSummary.regressions()).isEqualTo(0L) assertThat(metricSummary.unit()).isEqualTo("unit") - assertThat(metricSummary.diff()).contains(42.23) + assertThat(metricSummary.diff()).contains(0.0) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ObjectReferenceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ObjectReferenceTest.kt new file mode 100644 index 00000000..cd116d19 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ObjectReferenceTest.kt @@ -0,0 +1,27 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ObjectReferenceTest { + + @Test + fun createObjectReference() { + val objectReference = + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + assertThat(objectReference).isNotNull + assertThat(objectReference.id()).isEqualTo("id") + assertThat(objectReference._xactId()).isEqualTo("_xact_id") + assertThat(objectReference.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(objectReference.objectType()).isEqualTo(ObjectReference.ObjectType.EXPERIMENT) + assertThat(objectReference.created()).contains("created") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OnlineScoreConfigTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OnlineScoreConfigTest.kt index 1248b4b2..01f4d508 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OnlineScoreConfigTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OnlineScoreConfigTest.kt @@ -5,28 +5,24 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OnlineScoreConfigTest { +internal class OnlineScoreConfigTest { @Test fun createOnlineScoreConfig() { val onlineScoreConfig = OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() assertThat(onlineScoreConfig).isNotNull - assertThat(onlineScoreConfig.samplingRate()).isEqualTo(1.0) + assertThat(onlineScoreConfig.samplingRate()).isEqualTo(0.0) assertThat(onlineScoreConfig.scorers()) .containsExactly( OnlineScoreConfig.Scorer.ofFunction( diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationDeleteParamsTest.kt index 1c6fe6ac..7bd8b264 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationDeleteParamsTest { +internal class OrganizationDeleteParamsTest { @Test - fun createOrganizationDeleteParams() { + fun create() { OrganizationDeleteParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationListParamsTest.kt index 59b904b0..32cdfdf6 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationListParamsTest.kt @@ -2,52 +2,54 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationListParamsTest { +internal class OrganizationListParamsTest { @Test - fun createOrganizationListParams() { + fun create() { OrganizationListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(OrganizationListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = OrganizationListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(OrganizationListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - OrganizationListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = OrganizationListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParamsTest.kt index 99b5aca9..a9430430 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationMemberUpdateParamsTest.kt @@ -2,23 +2,23 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationMemberUpdateParamsTest { +internal class OrganizationMemberUpdateParamsTest { @Test - fun createOrganizationMemberUpdateParams() { + fun create() { OrganizationMemberUpdateParams.builder() .inviteUsers( OrganizationMemberUpdateParams.InviteUsers.builder() - .emails(listOf("string")) + .addEmail("string") .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .groupIds(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .groupNames(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupName("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .sendInviteEmails(true) .build() ) @@ -26,25 +26,25 @@ class OrganizationMemberUpdateParamsTest { .orgName("org_name") .removeUsers( OrganizationMemberUpdateParams.RemoveUsers.builder() - .emails(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addEmail("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) .build() } @Test - fun getBody() { + fun body() { val params = OrganizationMemberUpdateParams.builder() .inviteUsers( OrganizationMemberUpdateParams.InviteUsers.builder() - .emails(listOf("string")) + .addEmail("string") .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .groupIds(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .groupNames(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupName("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .sendInviteEmails(true) .build() ) @@ -52,40 +52,44 @@ class OrganizationMemberUpdateParamsTest { .orgName("org_name") .removeUsers( OrganizationMemberUpdateParams.RemoveUsers.builder() - .emails(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addEmail("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.inviteUsers()) - .isEqualTo( + .contains( OrganizationMemberUpdateParams.InviteUsers.builder() - .emails(listOf("string")) + .addEmail("string") .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .groupIds(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .groupNames(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupName("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .sendInviteEmails(true) .build() ) - assertThat(body.orgId()).isEqualTo("org_id") - assertThat(body.orgName()).isEqualTo("org_name") + assertThat(body.orgId()).contains("org_id") + assertThat(body.orgName()).contains("org_name") assertThat(body.removeUsers()) - .isEqualTo( + .contains( OrganizationMemberUpdateParams.RemoveUsers.builder() - .emails(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addEmail("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = OrganizationMemberUpdateParams.builder().build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParamsTest.kt index 4ccbda0e..b0f6faaf 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationRetrieveParamsTest { +internal class OrganizationRetrieveParamsTest { @Test - fun createOrganizationRetrieveParams() { + fun create() { OrganizationRetrieveParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationTest.kt index d458dc17..d5220152 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationTest { +internal class OrganizationTest { @Test fun createOrganization() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationUpdateParamsTest.kt index cc38ee32..f1cf977a 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/OrganizationUpdateParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class OrganizationUpdateParamsTest { +internal class OrganizationUpdateParamsTest { @Test - fun createOrganizationUpdateParams() { + fun create() { OrganizationUpdateParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .apiUrl("api_url") @@ -21,7 +21,7 @@ class OrganizationUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = OrganizationUpdateParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -31,23 +31,27 @@ class OrganizationUpdateParamsTest { .proxyUrl("proxy_url") .realtimeUrl("realtime_url") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.apiUrl()).isEqualTo("api_url") - assertThat(body.isUniversalApi()).isEqualTo(true) - assertThat(body.name()).isEqualTo("name") - assertThat(body.proxyUrl()).isEqualTo("proxy_url") - assertThat(body.realtimeUrl()).isEqualTo("realtime_url") + + val body = params._body() + + assertNotNull(body) + assertThat(body.apiUrl()).contains("api_url") + assertThat(body.isUniversalApi()).contains(true) + assertThat(body.name()).contains("name") + assertThat(body.proxyUrl()).contains("proxy_url") + assertThat(body.realtimeUrl()).contains("realtime_url") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = OrganizationUpdateParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutputTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutputTest.kt index 50747d77..8a00b5e5 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutputTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PatchOrganizationMembersOutputTest.kt @@ -5,16 +5,18 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PatchOrganizationMembersOutputTest { +internal class PatchOrganizationMembersOutputTest { @Test fun createPatchOrganizationMembersOutput() { val patchOrganizationMembersOutput = PatchOrganizationMembersOutput.builder() + .orgId("org_id") .status(PatchOrganizationMembersOutput.Status.SUCCESS) .sendEmailError("send_email_error") .build() assertThat(patchOrganizationMembersOutput).isNotNull + assertThat(patchOrganizationMembersOutput.orgId()).isEqualTo("org_id") assertThat(patchOrganizationMembersOutput.status()) .isEqualTo(PatchOrganizationMembersOutput.Status.SUCCESS) assertThat(patchOrganizationMembersOutput.sendEmailError()).contains("send_email_error") diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PathLookupFilterTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PathLookupFilterTest.kt deleted file mode 100755 index 4d32afc1..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PathLookupFilterTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import com.braintrustdata.api.core.JsonNull -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class PathLookupFilterTest { - - @Test - fun createPathLookupFilter() { - val pathLookupFilter = - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - assertThat(pathLookupFilter).isNotNull - assertThat(pathLookupFilter.path()).containsExactly("string") - assertThat(pathLookupFilter.type()).isEqualTo(PathLookupFilter.Type.PATH_LOOKUP) - assertThat(pathLookupFilter._value()).isEqualTo(JsonNull.of()) - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectCreateParamsTest.kt index 10928d7b..c9ffd874 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectCreateParamsTest.kt @@ -2,31 +2,35 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectCreateParamsTest { +internal class ProjectCreateParamsTest { @Test - fun createProjectCreateParams() { - ProjectCreateParams.builder().name("name").orgName("org_name").build() + fun create() { + ProjectCreateParams.builder().name("x").orgName("org_name").build() } @Test - fun getBody() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") - assertThat(body.orgName()).isEqualTo("org_name") + fun body() { + val params = ProjectCreateParams.builder().name("x").orgName("org_name").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { - val params = ProjectCreateParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + fun bodyWithoutOptionalFields() { + val params = ProjectCreateParams.builder().name("x").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectDeleteParamsTest.kt index caa2ac8b..3e30198e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectDeleteParamsTest { +internal class ProjectDeleteParamsTest { @Test - fun createProjectDeleteParams() { + fun create() { ProjectDeleteParams.builder().projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectListParamsTest.kt index 233ceaa7..9f6452cd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectListParamsTest.kt @@ -2,18 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectListParamsTest { +internal class ProjectListParamsTest { @Test - fun createProjectListParams() { + fun create() { ProjectListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectName("project_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -21,35 +21,38 @@ class ProjectListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ProjectListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectName("project_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - ProjectListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_name", "project_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_name", listOf("project_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ProjectListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParamsTest.kt index c2b19357..516e71e3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFeedbackParamsTest.kt @@ -2,76 +2,103 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectLogFeedbackParamsTest { +internal class ProjectLogFeedbackParamsTest { @Test - fun createProjectLogFeedbackParams() { + fun create() { ProjectLogFeedbackParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackProjectLogsItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackProjectLogsItem.Metadata.builder().build()) - .scores(FeedbackProjectLogsItem.Scores.builder().build()) - .source(FeedbackProjectLogsItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackProjectLogsItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = ProjectLogFeedbackParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackProjectLogsItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackProjectLogsItem.Metadata.builder().build()) - .scores(FeedbackProjectLogsItem.Scores.builder().build()) - .source(FeedbackProjectLogsItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackProjectLogsItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo( listOf( FeedbackProjectLogsItem.builder() .id("id") .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackProjectLogsItem.Metadata.builder().build()) - .scores(FeedbackProjectLogsItem.Scores.builder().build()) + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectLogFeedbackParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackProjectLogsItem.builder().id("id").build())) + .addFeedback(FeedbackProjectLogsItem.builder().id("id").build()) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.feedback()) .isEqualTo(listOf(FeedbackProjectLogsItem.builder().id("id").build())) } @@ -81,7 +108,7 @@ class ProjectLogFeedbackParamsTest { val params = ProjectLogFeedbackParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback(listOf(FeedbackProjectLogsItem.builder().id("id").build())) + .addFeedback(FeedbackProjectLogsItem.builder().id("id").build()) .build() assertThat(params).isNotNull // path param "projectId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchParamsTest.kt index c84026c0..2f305737 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchParamsTest.kt @@ -2,17 +2,17 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectLogFetchParamsTest { +internal class ProjectLogFetchParamsTest { @Test - fun createProjectLogFetchParams() { + fun create() { ProjectLogFetchParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -20,31 +20,39 @@ class ProjectLogFetchParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ProjectLogFetchParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val expected = mutableMapOf>() - expected.put("limit", listOf("123")) - expected.put("max_root_span_id", listOf("max_root_span_id")) - expected.put("max_xact_id", listOf("max_xact_id")) - expected.put("version", listOf("version")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("limit", "0") + .put("max_root_span_id", "max_root_span_id") + .put("max_xact_id", "max_xact_id") + .put("version", "version") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ProjectLogFetchParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParamsTest.kt index acb4cc3d..6bed5b0e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogFetchPostParamsTest.kt @@ -2,28 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectLogFetchPostParamsTest { +internal class ProjectLogFetchPostParamsTest { @Test - fun createProjectLogFetchPostParams() { + fun create() { ProjectLogFetchPostParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") @@ -31,52 +21,37 @@ class ProjectLogFetchPostParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectLogFetchPostParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.cursor()).isEqualTo("cursor") - assertThat(body.filters()) - .isEqualTo( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - assertThat(body.limit()).isEqualTo(123L) - assertThat(body.maxRootSpanId()).isEqualTo("max_root_span_id") - assertThat(body.maxXactId()).isEqualTo("max_xact_id") - assertThat(body.version()).isEqualTo("version") + + val body = params._body() + + assertNotNull(body) + assertThat(body.cursor()).contains("cursor") + assertThat(body.limit()).contains(0L) + assertThat(body.maxRootSpanId()).contains("max_root_span_id") + assertThat(body.maxXactId()).contains("max_xact_id") + assertThat(body.version()).contains("version") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectLogFetchPostParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogInsertParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogInsertParamsTest.kt index 4540c135..d238976b 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogInsertParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogInsertParamsTest.kt @@ -2,181 +2,213 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectLogInsertParamsTest { +internal class ProjectLogInsertParamsTest { @Test - fun createProjectLogInsertParams() { + fun create() { ProjectLogInsertParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder() + .addEvent( + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertProjectLogsEvent.Metadata.builder().model("model").build()) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertProjectLogsEventReplace.Metadata.builder().build()) - .metrics( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventReplace.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() } @Test - fun getBody() { + fun body() { val params = ProjectLogInsertParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder() + .addEvent( + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertProjectLogsEvent.Metadata.builder().model("model").build()) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertProjectLogsEventReplace.Metadata.builder().build()) - .metrics( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventReplace.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.events()) .isEqualTo( listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder() - .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertProjectLogsEventReplace.Metadata.builder().build()) - .metrics( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventReplace.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type(InsertProjectLogsEventReplace.SpanAttributes.Type.LLM) - .build() - ) - .tags(listOf("string")) - .build() - ) + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertProjectLogsEvent.Metadata.builder().model("model").build()) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectLogInsertParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertProjectLogsEvent.builder().build()) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.events()) - .isEqualTo( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder().build() - ) - ) - ) + + val body = params._body() + + assertNotNull(body) + assertThat(body.events()).isEqualTo(listOf(InsertProjectLogsEvent.builder().build())) } @Test @@ -184,13 +216,7 @@ class ProjectLogInsertParamsTest { val params = ProjectLogInsertParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder().build() - ) - ) - ) + .addEvent(InsertProjectLogsEvent.builder().build()) .build() assertThat(params).isNotNull // path param "projectId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogsEventTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogsEventTest.kt index 34b0430b..ac983318 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogsEventTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectLogsEventTest.kt @@ -2,12 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectLogsEventTest { +internal class ProjectLogsEventTest { @Test fun createProjectLogsEvent() { @@ -25,32 +25,44 @@ class ProjectLogsEventTest { ProjectLogsEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(ProjectLogsEvent.Metadata.builder().build()) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .isRoot(true) + .metadata(ProjectLogsEvent.Metadata.builder().model("model").build()) .metrics( ProjectLogsEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - .output(JsonNull.of()) - .scores(ProjectLogsEvent.Scores.builder().build()) - .spanAttributes( - ProjectLogsEvent.SpanAttributes.builder() - .name("name") - .type(ProjectLogsEvent.SpanAttributes.Type.LLM) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - .spanParents(listOf("string")) - .tags(listOf("string")) + .output(JsonValue.from(mapOf())) + .scores( + ProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) + .addSpanParent("string") + .addTag("string") .build() assertThat(projectLogsEvent).isNotNull assertThat(projectLogsEvent.id()).isEqualTo("id") @@ -67,33 +79,47 @@ class ProjectLogsEventTest { ProjectLogsEvent.Context.builder() .callerFilename("caller_filename") .callerFunctionname("caller_functionname") - .callerLineno(123L) + .callerLineno(0L) .build() ) - assertThat(projectLogsEvent._error()).isEqualTo(JsonNull.of()) - assertThat(projectLogsEvent._expected()).isEqualTo(JsonNull.of()) - assertThat(projectLogsEvent._input()).isEqualTo(JsonNull.of()) + assertThat(projectLogsEvent._error()).isEqualTo(JsonValue.from(mapOf())) + assertThat(projectLogsEvent._expected()).isEqualTo(JsonValue.from(mapOf())) + assertThat(projectLogsEvent._input()).isEqualTo(JsonValue.from(mapOf())) + assertThat(projectLogsEvent.isRoot()).contains(true) assertThat(projectLogsEvent.metadata()) - .contains(ProjectLogsEvent.Metadata.builder().build()) + .contains(ProjectLogsEvent.Metadata.builder().model("model").build()) assertThat(projectLogsEvent.metrics()) .contains( ProjectLogsEvent.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) .build() ) - assertThat(projectLogsEvent._output()).isEqualTo(JsonNull.of()) - assertThat(projectLogsEvent.scores()).contains(ProjectLogsEvent.Scores.builder().build()) - assertThat(projectLogsEvent.spanAttributes()) + assertThat(projectLogsEvent.origin()) .contains( - ProjectLogsEvent.SpanAttributes.builder() - .name("name") - .type(ProjectLogsEvent.SpanAttributes.Type.LLM) + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) + assertThat(projectLogsEvent._output()).isEqualTo(JsonValue.from(mapOf())) + assertThat(projectLogsEvent.scores()) + .contains( + ProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + assertThat(projectLogsEvent.spanAttributes()) + .contains(SpanAttributes.builder().name("name").type(SpanType.LLM).build()) assertThat(projectLogsEvent.spanParents().get()).containsExactly("string") assertThat(projectLogsEvent.tags().get()).containsExactly("string") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectRetrieveParamsTest.kt index 231a1864..ad7bf543 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectRetrieveParamsTest { +internal class ProjectRetrieveParamsTest { @Test - fun createProjectRetrieveParams() { + fun create() { ProjectRetrieveParams.builder().projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCategoryTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCategoryTest.kt index a190a270..eb62ebe7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCategoryTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCategoryTest.kt @@ -5,13 +5,13 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreCategoryTest { +internal class ProjectScoreCategoryTest { @Test fun createProjectScoreCategory() { - val projectScoreCategory = ProjectScoreCategory.builder().name("name").value(42.23).build() + val projectScoreCategory = ProjectScoreCategory.builder().name("name").value(0.0).build() assertThat(projectScoreCategory).isNotNull assertThat(projectScoreCategory.name()).isEqualTo("name") - assertThat(projectScoreCategory.value()).isEqualTo(42.23) + assertThat(projectScoreCategory.value()).isEqualTo(0.0) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreConfigTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreConfigTest.kt index 7639e899..40346457 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreConfigTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreConfigTest.kt @@ -5,52 +5,43 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreConfigTest { +internal class ProjectScoreConfigTest { @Test fun createProjectScoreConfig() { val projectScoreConfig = ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() assertThat(projectScoreConfig).isNotNull - assertThat(projectScoreConfig.destination()) - .contains(ProjectScoreConfig.Destination.EXPECTED) + assertThat(projectScoreConfig.destination()).contains("destination") assertThat(projectScoreConfig.multiSelect()).contains(true) assertThat(projectScoreConfig.online()) .contains( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParamsTest.kt index a2b3b31e..af4c04c3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreCreateParamsTest.kt @@ -2,40 +2,36 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreCreateParamsTest { +internal class ProjectScoreCreateParamsTest { @Test - fun createProjectScoreCreateParams() { + fun create() { ProjectScoreCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -45,90 +41,84 @@ class ProjectScoreCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectScoreCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type.FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() ) .description("description") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.scoreType()).isEqualTo(ProjectScoreType.SLIDER) assertThat(body.categories()) - .isEqualTo( - ProjectScoreCreateParams.Categories.ofProjectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .contains( + ProjectScoreCreateParams.Categories.ofCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) ) assertThat(body.config()) - .isEqualTo( + .contains( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() ) - assertThat(body.description()).isEqualTo("description") + assertThat(body.description()).contains("description") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectScoreCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.scoreType()).isEqualTo(ProjectScoreType.SLIDER) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParamsTest.kt index 896f79a5..3ba5951f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreDeleteParamsTest { +internal class ProjectScoreDeleteParamsTest { @Test - fun createProjectScoreDeleteParams() { + fun create() { ProjectScoreDeleteParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreListParamsTest.kt index 7832ecb6..e1ff4653 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreListParamsTest.kt @@ -2,72 +2,66 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreListParamsTest { +internal class ProjectScoreListParamsTest { @Test - fun createProjectScoreListParams() { + fun create() { ProjectScoreListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectScoreListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") .projectScoreName("project_score_name") - .scoreType(ProjectScoreListParams.ScoreType.ofProjectScoreType(ProjectScoreType.SLIDER)) + .scoreType(ProjectScoreType.SLIDER) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = ProjectScoreListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectScoreListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") .projectScoreName("project_score_name") - .scoreType( - ProjectScoreListParams.ScoreType.ofProjectScoreType(ProjectScoreType.SLIDER) - ) + .scoreType(ProjectScoreType.SLIDER) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - ProjectScoreListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .toString() - ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("project_score_name", listOf("project_score_name")) - expected.put( - "score_type", - listOf( - ProjectScoreListParams.ScoreType.ofProjectScoreType(ProjectScoreType.SLIDER) - .toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("project_score_name", "project_score_name") + .put("score_type", "slider") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ProjectScoreListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParamsTest.kt index dd18f1f5..50960ecf 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreReplaceParamsTest.kt @@ -2,40 +2,36 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreReplaceParamsTest { +internal class ProjectScoreReplaceParamsTest { @Test - fun createProjectScoreReplaceParams() { + fun create() { ProjectScoreReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -45,90 +41,84 @@ class ProjectScoreReplaceParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectScoreReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type.FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() ) .description("description") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.scoreType()).isEqualTo(ProjectScoreType.SLIDER) assertThat(body.categories()) - .isEqualTo( - ProjectScoreReplaceParams.Categories.ofProjectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .contains( + ProjectScoreReplaceParams.Categories.ofCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) ) assertThat(body.config()) - .isEqualTo( + .contains( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() ) - assertThat(body.description()).isEqualTo("description") + assertThat(body.description()).contains("description") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectScoreReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.scoreType()).isEqualTo(ProjectScoreType.SLIDER) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParamsTest.kt index 9237a10b..a6f2bd61 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreRetrieveParamsTest { +internal class ProjectScoreRetrieveParamsTest { @Test - fun createProjectScoreRetrieveParams() { + fun create() { ProjectScoreRetrieveParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreTest.kt index 1ae89d7b..576f47a4 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreTest { +internal class ProjectScoreTest { @Test fun createProjectScore() { @@ -17,32 +17,24 @@ class ProjectScoreTest { .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .categories( - ProjectScore.Categories.ofProjectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) - ) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type.FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -59,30 +51,26 @@ class ProjectScoreTest { assertThat(projectScore.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(projectScore.categories()) .contains( - ProjectScore.Categories.ofProjectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + ProjectScore.Categories.ofCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) ) assertThat(projectScore.config()) .contains( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParamsTest.kt index 68073495..5c2a615d 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectScoreUpdateParamsTest.kt @@ -2,38 +2,34 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectScoreUpdateParamsTest { +internal class ProjectScoreUpdateParamsTest { @Test - fun createProjectScoreUpdateParams() { + fun create() { ProjectScoreUpdateParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -45,34 +41,28 @@ class ProjectScoreUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectScoreUpdateParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type.FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -81,51 +71,51 @@ class ProjectScoreUpdateParamsTest { .name("name") .scoreType(ProjectScoreType.SLIDER) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.categories()) - .isEqualTo( - ProjectScoreUpdateParams.Categories.ofProjectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .contains( + ProjectScoreUpdateParams.Categories.ofCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) ) assertThat(body.config()) - .isEqualTo( + .contains( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() ) - assertThat(body.description()).isEqualTo("description") - assertThat(body.name()).isEqualTo("name") - assertThat(body.scoreType()).isEqualTo(ProjectScoreType.SLIDER) + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("name") + assertThat(body.scoreType()).contains(ProjectScoreType.SLIDER) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectScoreUpdateParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectSettingsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectSettingsTest.kt index 0624066d..7a9c2f21 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectSettingsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectSettingsTest.kt @@ -5,12 +5,35 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectSettingsTest { +internal class ProjectSettingsTest { @Test fun createProjectSettings() { - val projectSettings = ProjectSettings.builder().comparisonKey("comparison_key").build() + val projectSettings = + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() assertThat(projectSettings).isNotNull + assertThat(projectSettings.baselineExperimentId()) + .contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(projectSettings.comparisonKey()).contains("comparison_key") + assertThat(projectSettings.spanFieldOrder().get()) + .containsExactly( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagCreateParamsTest.kt index 111ab845..221e1eb7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagCreateParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagCreateParamsTest { +internal class ProjectTagCreateParamsTest { @Test - fun createProjectTagCreateParams() { + fun create() { ProjectTagCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -19,7 +19,7 @@ class ProjectTagCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectTagCreateParams.builder() .name("name") @@ -27,23 +27,27 @@ class ProjectTagCreateParamsTest { .color("color") .description("description") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.color()).isEqualTo("color") - assertThat(body.description()).isEqualTo("description") + assertThat(body.color()).contains("color") + assertThat(body.description()).contains("description") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectTagCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParamsTest.kt index 12369e03..7de39ed3 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagDeleteParamsTest { +internal class ProjectTagDeleteParamsTest { @Test - fun createProjectTagDeleteParams() { + fun create() { ProjectTagDeleteParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagListParamsTest.kt index 091272bb..5b43e3ad 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagListParamsTest.kt @@ -2,18 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagListParamsTest { +internal class ProjectTagListParamsTest { @Test - fun createProjectTagListParams() { + fun create() { ProjectTagListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectTagListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -23,39 +23,42 @@ class ProjectTagListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = ProjectTagListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ProjectTagListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") .projectTagName("project_tag_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf( - ProjectTagListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("project_tag_name", "project_tag_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("project_tag_name", listOf("project_tag_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ProjectTagListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParamsTest.kt index bec95fa1..c3c2cb8c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagReplaceParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagReplaceParamsTest { +internal class ProjectTagReplaceParamsTest { @Test - fun createProjectTagReplaceParams() { + fun create() { ProjectTagReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -19,7 +19,7 @@ class ProjectTagReplaceParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectTagReplaceParams.builder() .name("name") @@ -27,23 +27,27 @@ class ProjectTagReplaceParamsTest { .color("color") .description("description") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.color()).isEqualTo("color") - assertThat(body.description()).isEqualTo("description") + assertThat(body.color()).contains("color") + assertThat(body.description()).contains("description") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectTagReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParamsTest.kt index cd792595..bceb5438 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagRetrieveParamsTest { +internal class ProjectTagRetrieveParamsTest { @Test - fun createProjectTagRetrieveParams() { + fun create() { ProjectTagRetrieveParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagTest.kt index d9a83759..23968bbb 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagTest { +internal class ProjectTagTest { @Test fun createProjectTag() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParamsTest.kt index 9b5ac6a1..0bda9b77 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTagUpdateParamsTest.kt @@ -2,14 +2,14 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTagUpdateParamsTest { +internal class ProjectTagUpdateParamsTest { @Test - fun createProjectTagUpdateParams() { + fun create() { ProjectTagUpdateParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .color("color") @@ -19,7 +19,7 @@ class ProjectTagUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = ProjectTagUpdateParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -27,21 +27,25 @@ class ProjectTagUpdateParamsTest { .description("description") .name("name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.color()).isEqualTo("color") - assertThat(body.description()).isEqualTo("description") - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.color()).contains("color") + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("name") } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectTagUpdateParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTest.kt index 390af485..15ac6b29 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectTest { +internal class ProjectTest { @Test fun createProject() { @@ -17,7 +17,20 @@ class ProjectTest { .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .settings( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() assertThat(project).isNotNull @@ -27,7 +40,20 @@ class ProjectTest { assertThat(project.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(project.deletedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(project.settings()) - .contains(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .contains( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) assertThat(project.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectUpdateParamsTest.kt index 9ea7f42d..231a5855 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ProjectUpdateParamsTest.kt @@ -2,42 +2,85 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ProjectUpdateParamsTest { +internal class ProjectUpdateParamsTest { @Test - fun createProjectUpdateParams() { + fun create() { ProjectUpdateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .settings( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) .build() } @Test - fun getBody() { + fun body() { val params = ProjectUpdateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .settings( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).contains("name") assertThat(body.settings()) - .isEqualTo(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .contains( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ProjectUpdateParams.builder().projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptCreateParamsTest.kt index f7b21942..4b481b7f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptCreateParamsTest.kt @@ -2,60 +2,64 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptCreateParamsTest { +internal class PromptCreateParamsTest { @Test - fun createPromptCreateParams() { + fun create() { PromptCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptCreateParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -69,85 +73,86 @@ class PromptCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = PromptCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptCreateParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -161,81 +166,84 @@ class PromptCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") - assertThat(body.description()).isEqualTo("description") - assertThat(body.functionType()).isEqualTo(PromptCreateParams.FunctionType.LLM) + assertThat(body.slug()).isEqualTo("x") + assertThat(body.description()).contains("description") + assertThat(body.functionType()).contains(PromptCreateParams.FunctionType.LLM) assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -249,46 +257,46 @@ class PromptCreateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = PromptCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") + assertThat(body.slug()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDataTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDataTest.kt index ac9b23aa..88789045 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDataTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDataTest.kt @@ -2,52 +2,53 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptDataTest { +internal class PromptDataTest { @Test fun createPromptData() { val promptData = PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams.ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall.UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice.UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -61,67 +62,66 @@ class PromptDataTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() assertThat(promptData).isNotNull assertThat(promptData.options()) .contains( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall.ofAuto( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .Auto - .AUTO + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall.UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .Type + .JSON_OBJECT ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams.ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice.UnionMember0.AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -137,7 +137,11 @@ class PromptDataTest { assertThat(promptData.parser()) .contains( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDeleteParamsTest.kt index a819f9d2..5fa9d727 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptDeleteParamsTest { +internal class PromptDeleteParamsTest { @Test - fun createPromptDeleteParams() { + fun create() { PromptDeleteParams.builder().promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptListParamsTest.kt index a2c57163..ef6a5e48 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptListParamsTest.kt @@ -2,18 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptListParamsTest { +internal class PromptListParamsTest { @Test - fun createPromptListParams() { + fun create() { PromptListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(PromptListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -25,12 +25,12 @@ class PromptListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = PromptListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(PromptListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .projectName("project_name") @@ -39,27 +39,32 @@ class PromptListParamsTest { .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .version("version") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf(PromptListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("project_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("project_name", listOf("project_name")) - expected.put("prompt_name", listOf("prompt_name")) - expected.put("slug", listOf("slug")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("version", listOf("version")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("project_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("project_name", "project_name") + .put("prompt_name", "prompt_name") + .put("slug", "slug") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("version", "version") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = PromptListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptOptionsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptOptionsTest.kt new file mode 100644 index 00000000..05a4e211 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptOptionsTest.kt @@ -0,0 +1,84 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class PromptOptionsTest { + + @Test + fun createPromptOptions() { + val promptOptions = + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall.UnionMember0.AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort(PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice.UnionMember0.AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + assertThat(promptOptions).isNotNull + assertThat(promptOptions.model()).contains("model") + assertThat(promptOptions.params()) + .contains( + PromptOptions.Params.ofOpenAIModel( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall.UnionMember0.AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort(PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams.ResponseFormat.JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice.UnionMember0.AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + ) + assertThat(promptOptions.position()).contains("position") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptReplaceParamsTest.kt index 3031f48e..a3b083cf 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptReplaceParamsTest.kt @@ -2,60 +2,64 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptReplaceParamsTest { +internal class PromptReplaceParamsTest { @Test - fun createPromptReplaceParams() { + fun create() { PromptReplaceParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptReplaceParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -69,85 +73,86 @@ class PromptReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = PromptReplaceParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptReplaceParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -161,81 +166,84 @@ class PromptReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") - assertThat(body.description()).isEqualTo("description") - assertThat(body.functionType()).isEqualTo(PromptReplaceParams.FunctionType.LLM) + assertThat(body.slug()).isEqualTo("x") + assertThat(body.description()).contains("description") + assertThat(body.functionType()).contains(PromptReplaceParams.FunctionType.LLM) assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -249,46 +257,46 @@ class PromptReplaceParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = PromptReplaceParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.slug()).isEqualTo("slug") + assertThat(body.slug()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptRetrieveParamsTest.kt index d8aa5099..a5915832 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptRetrieveParamsTest { +internal class PromptRetrieveParamsTest { @Test - fun createPromptRetrieveParams() { + fun create() { PromptRetrieveParams.builder().promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptTest.kt index cfdb0275..15360d72 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptTest.kt @@ -2,11 +2,12 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptTest { +internal class PromptTest { @Test fun createPrompt() { @@ -22,48 +23,55 @@ class PromptTest { .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .description("description") .functionType(Prompt.FunctionType.LLM) - .metadata(Prompt.Metadata.builder().build()) + .metadata( + Prompt.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -77,32 +85,30 @@ class PromptTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() assertThat(prompt).isNotNull assertThat(prompt.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -115,48 +121,56 @@ class PromptTest { assertThat(prompt.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(prompt.description()).contains("description") assertThat(prompt.functionType()).contains(Prompt.FunctionType.LLM) - assertThat(prompt.metadata()).contains(Prompt.Metadata.builder().build()) + assertThat(prompt.metadata()) + .contains( + Prompt.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) assertThat(prompt.promptData()) .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -170,28 +184,26 @@ class PromptTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptUpdateParamsTest.kt index c75ca8b0..70bfe5a7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/PromptUpdateParamsTest.kt @@ -2,14 +2,15 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class PromptUpdateParamsTest { +internal class PromptUpdateParamsTest { @Test - fun createPromptUpdateParams() { + fun create() { PromptUpdateParams.builder() .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") @@ -17,43 +18,46 @@ class PromptUpdateParamsTest { .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -67,38 +71,36 @@ class PromptUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) .slug("slug") - .tags(listOf("string")) + .addTag("string") .build() } @Test - fun getBody() { + fun body() { val params = PromptUpdateParams.builder() .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -107,44 +109,47 @@ class PromptUpdateParamsTest { .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -158,79 +163,82 @@ class PromptUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) .slug("slug") - .tags(listOf("string")) + .addTag("string") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.description()).isEqualTo("description") - assertThat(body.name()).isEqualTo("name") + + val body = params._body() + + assertNotNull(body) + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("name") assertThat(body.promptData()) - .isEqualTo( + .contains( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams.FunctionCall - .ofAuto( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams.ReasoningEffort.LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams.ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -244,41 +252,41 @@ class PromptUpdateParamsTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - assertThat(body.slug()).isEqualTo("slug") - assertThat(body.tags()).isEqualTo(listOf("string")) + assertThat(body.slug()).contains("slug") + assertThat(body.tags()).contains(listOf("string")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = PromptUpdateParams.builder().promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RepoInfoTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RepoInfoTest.kt index 83eec5e0..402272fd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RepoInfoTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RepoInfoTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RepoInfoTest { +internal class RepoInfoTest { @Test fun createRepoInfo() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleCreateParamsTest.kt index e4500a98..9310f639 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleCreateParamsTest.kt @@ -2,75 +2,69 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleCreateParamsTest { +internal class RoleCreateParamsTest { @Test - fun createRoleCreateParams() { + fun create() { RoleCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleCreateParams.MemberPermission.builder() - .permission(RoleCreateParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleCreateParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleCreateParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() } @Test - fun getBody() { + fun body() { val params = RoleCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleCreateParams.MemberPermission.builder() - .permission(RoleCreateParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleCreateParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleCreateParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") - assertThat(body.description()).isEqualTo("description") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") + assertThat(body.description()).contains("description") assertThat(body.memberPermissions()) - .isEqualTo( + .contains( listOf( RoleCreateParams.MemberPermission.builder() - .permission(RoleCreateParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleCreateParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .build() ) ) - assertThat(body.memberRoles()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.orgName()).isEqualTo("org_name") + assertThat(body.memberRoles()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { - val params = RoleCreateParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + fun bodyWithoutOptionalFields() { + val params = RoleCreateParams.builder().name("x").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleDeleteParamsTest.kt index df2e651a..6552fe89 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleDeleteParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleDeleteParamsTest { +internal class RoleDeleteParamsTest { @Test - fun createRoleDeleteParams() { + fun create() { RoleDeleteParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleListParamsTest.kt index 2db9679b..c023fec1 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleListParamsTest.kt @@ -2,18 +2,18 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleListParamsTest { +internal class RoleListParamsTest { @Test - fun createRoleListParams() { + fun create() { RoleListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(RoleListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .roleName("role_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -21,33 +21,38 @@ class RoleListParamsTest { } @Test - fun getQueryParams() { + fun queryParams() { val params = RoleListParams.builder() .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(RoleListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .roleName("role_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf(RoleListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("role_name", listOf("role_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("role_name", "role_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = RoleListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleReplaceParamsTest.kt index 299ccd32..d278709c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleReplaceParamsTest.kt @@ -2,75 +2,69 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleReplaceParamsTest { +internal class RoleReplaceParamsTest { @Test - fun createRoleReplaceParams() { + fun create() { RoleReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleReplaceParams.MemberPermission.builder() - .permission(RoleReplaceParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleReplaceParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleReplaceParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() } @Test - fun getBody() { + fun body() { val params = RoleReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleReplaceParams.MemberPermission.builder() - .permission(RoleReplaceParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleReplaceParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleReplaceParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") - assertThat(body.description()).isEqualTo("description") + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") + assertThat(body.description()).contains("description") assertThat(body.memberPermissions()) - .isEqualTo( + .contains( listOf( RoleReplaceParams.MemberPermission.builder() - .permission(RoleReplaceParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleReplaceParams.MemberPermission.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .build() ) ) - assertThat(body.memberRoles()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.orgName()).isEqualTo("org_name") + assertThat(body.memberRoles()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.orgName()).contains("org_name") } @Test - fun getBodyWithoutOptionalFields() { - val params = RoleReplaceParams.builder().name("name").build() - val body = params.getBody() - assertThat(body).isNotNull - assertThat(body.name()).isEqualTo("name") + fun bodyWithoutOptionalFields() { + val params = RoleReplaceParams.builder().name("x").build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("x") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleRetrieveParamsTest.kt index d0791c4d..72b41378 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleRetrieveParamsTest { +internal class RoleRetrieveParamsTest { @Test - fun createRoleRetrieveParams() { + fun create() { RoleRetrieveParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleTest.kt index c2325951..c3adf0e4 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleTest { +internal class RoleTest { @Test fun createRole() { @@ -17,17 +17,13 @@ class RoleTest { .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .description("description") - .memberPermissions( - listOf( - Role.MemberPermission.builder() - .permission(Role.MemberPermission.Permission.CREATE) - .restrictObjectType( - Role.MemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addMemberPermission( + Role.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() @@ -40,8 +36,8 @@ class RoleTest { assertThat(role.memberPermissions().get()) .containsExactly( Role.MemberPermission.builder() - .permission(Role.MemberPermission.Permission.CREATE) - .restrictObjectType(Role.MemberPermission.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .build() ) assertThat(role.memberRoles().get()).containsExactly("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleUpdateParamsTest.kt index 46274c48..5108aba7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/RoleUpdateParamsTest.kt @@ -2,111 +2,94 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class RoleUpdateParamsTest { +internal class RoleUpdateParamsTest { @Test - fun createRoleUpdateParams() { + fun create() { RoleUpdateParams.builder() .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberPermissions( - listOf( - RoleUpdateParams.AddMemberPermission.builder() - .permission(RoleUpdateParams.AddMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.AddMemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addAddMemberPermission( + RoleUpdateParams.AddMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .addMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberPermissions( - listOf( - RoleUpdateParams.RemoveMemberPermission.builder() - .permission(RoleUpdateParams.RemoveMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.RemoveMemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .name("x") + .addRemoveMemberPermission( + RoleUpdateParams.RemoveMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .removeMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addRemoveMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getBody() { + fun body() { val params = RoleUpdateParams.builder() .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberPermissions( - listOf( - RoleUpdateParams.AddMemberPermission.builder() - .permission(RoleUpdateParams.AddMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.AddMemberPermission.RestrictObjectType.ORGANIZATION - ) - .build() - ) + .addAddMemberPermission( + RoleUpdateParams.AddMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .addMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberPermissions( - listOf( - RoleUpdateParams.RemoveMemberPermission.builder() - .permission(RoleUpdateParams.RemoveMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.RemoveMemberPermission.RestrictObjectType - .ORGANIZATION - ) - .build() - ) + .name("x") + .addRemoveMemberPermission( + RoleUpdateParams.RemoveMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .removeMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addRemoveMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.addMemberPermissions()) - .isEqualTo( + .contains( listOf( RoleUpdateParams.AddMemberPermission.builder() - .permission(RoleUpdateParams.AddMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.AddMemberPermission.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .build() ) ) - assertThat(body.addMemberRoles()).isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(body.description()).isEqualTo("description") - assertThat(body.name()).isEqualTo("name") + assertThat(body.addMemberRoles()).contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("x") assertThat(body.removeMemberPermissions()) - .isEqualTo( + .contains( listOf( RoleUpdateParams.RemoveMemberPermission.builder() - .permission(RoleUpdateParams.RemoveMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.RemoveMemberPermission.RestrictObjectType.ORGANIZATION - ) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .build() ) ) assertThat(body.removeMemberRoles()) - .isEqualTo(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .contains(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = RoleUpdateParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) } @Test diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScoreSummaryTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScoreSummaryTest.kt index 8081fbbc..e37b5561 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScoreSummaryTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScoreSummaryTest.kt @@ -5,23 +5,23 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ScoreSummaryTest { +internal class ScoreSummaryTest { @Test fun createScoreSummary() { val scoreSummary = ScoreSummary.builder() - .improvements(123L) + .improvements(0L) .name("name") - .regressions(123L) - .score(1.0) - .diff(1.0) + .regressions(0L) + .score(0.0) + .diff(-1.0) .build() assertThat(scoreSummary).isNotNull - assertThat(scoreSummary.improvements()).isEqualTo(123L) + assertThat(scoreSummary.improvements()).isEqualTo(0L) assertThat(scoreSummary.name()).isEqualTo("name") - assertThat(scoreSummary.regressions()).isEqualTo(123L) - assertThat(scoreSummary.score()).isEqualTo(1.0) - assertThat(scoreSummary.diff()).contains(1.0) + assertThat(scoreSummary.regressions()).isEqualTo(0L) + assertThat(scoreSummary.score()).isEqualTo(0.0) + assertThat(scoreSummary.diff()).contains(-1.0) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScorerTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScorerTest.kt deleted file mode 100644 index 3c30d63c..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ScorerTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class ScorerTest { - - @Test - fun createScorer() { - val scorer = Scorer.builder().index(123L).type(Scorer.Type.SCORER).build() - assertThat(scorer).isNotNull - assertThat(scorer.index()).isEqualTo(123L) - assertThat(scorer.type()).isEqualTo(Scorer.Type.SCORER) - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanAttributesTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanAttributesTest.kt new file mode 100644 index 00000000..c8368446 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanAttributesTest.kt @@ -0,0 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanAttributesTest { + + @Test + fun createSpanAttributes() { + val spanAttributes = SpanAttributes.builder().name("name").type(SpanType.LLM).build() + assertThat(spanAttributes).isNotNull + assertThat(spanAttributes.name()).contains("name") + assertThat(spanAttributes.type()).contains(SpanType.LLM) + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIFrameTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIFrameTest.kt new file mode 100644 index 00000000..13eb4eef --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIFrameTest.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIFrameTest { + + @Test + fun createSpanIFrame() { + val spanIFrame = + SpanIFrame.builder() + .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .description("description") + .postMessage(true) + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + assertThat(spanIFrame).isNotNull + assertThat(spanIFrame.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(spanIFrame.name()).isEqualTo("name") + assertThat(spanIFrame.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(spanIFrame.url()).isEqualTo("url") + assertThat(spanIFrame.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(spanIFrame.deletedAt()) + .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(spanIFrame.description()).contains("description") + assertThat(spanIFrame.postMessage()).contains(true) + assertThat(spanIFrame.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeCreateParamsTest.kt new file mode 100644 index 00000000..16fcf240 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeCreateParamsTest.kt @@ -0,0 +1,59 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import kotlin.test.assertNotNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeCreateParamsTest { + + @Test + fun create() { + SpanIframeCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + } + + @Test + fun body() { + val params = + SpanIframeCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("name") + assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.url()).isEqualTo("url") + assertThat(body.description()).contains("description") + assertThat(body.postMessage()).contains(true) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SpanIframeCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("name") + assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.url()).isEqualTo("url") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParamsTest.kt new file mode 100644 index 00000000..a2f0c37f --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeDeleteParamsTest.kt @@ -0,0 +1,29 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeDeleteParamsTest { + + @Test + fun create() { + SpanIframeDeleteParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun getPathParam() { + val params = + SpanIframeDeleteParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + assertThat(params).isNotNull + // path param "spanIframeId" + assertThat(params.getPathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params.getPathParam(1)).isEqualTo("") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeListParamsTest.kt new file mode 100644 index 00000000..47aed4d6 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeListParamsTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import com.braintrustdata.api.core.http.QueryParams +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeListParamsTest { + + @Test + fun create() { + SpanIframeListParams.builder() + .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .orgName("org_name") + .spanIframeName("span_iframe_name") + .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun queryParams() { + val params = + SpanIframeListParams.builder() + .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .orgName("org_name") + .spanIframeName("span_iframe_name") + .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("span_iframe_name", "span_iframe_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = SpanIframeListParams.builder().build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParamsTest.kt new file mode 100644 index 00000000..f641330c --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeReplaceParamsTest.kt @@ -0,0 +1,59 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import kotlin.test.assertNotNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeReplaceParamsTest { + + @Test + fun create() { + SpanIframeReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + } + + @Test + fun body() { + val params = + SpanIframeReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("name") + assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.url()).isEqualTo("url") + assertThat(body.description()).contains("description") + assertThat(body.postMessage()).contains(true) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SpanIframeReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.name()).isEqualTo("name") + assertThat(body.projectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.url()).isEqualTo("url") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParamsTest.kt new file mode 100644 index 00000000..adab9365 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeRetrieveParamsTest.kt @@ -0,0 +1,29 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeRetrieveParamsTest { + + @Test + fun create() { + SpanIframeRetrieveParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun getPathParam() { + val params = + SpanIframeRetrieveParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + assertThat(params).isNotNull + // path param "spanIframeId" + assertThat(params.getPathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params.getPathParam(1)).isEqualTo("") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParamsTest.kt new file mode 100644 index 00000000..fd52b975 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SpanIframeUpdateParamsTest.kt @@ -0,0 +1,66 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.models + +import kotlin.test.assertNotNull +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SpanIframeUpdateParamsTest { + + @Test + fun create() { + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("name") + .postMessage(true) + .url("url") + .build() + } + + @Test + fun body() { + val params = + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("name") + .postMessage(true) + .url("url") + .build() + + val body = params._body() + + assertNotNull(body) + assertThat(body.description()).contains("description") + assertThat(body.name()).contains("name") + assertThat(body.postMessage()).contains(true) + assertThat(body.url()).contains("url") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + val body = params._body() + + assertNotNull(body) + } + + @Test + fun getPathParam() { + val params = + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + assertThat(params).isNotNull + // path param "spanIframeId" + assertThat(params.getPathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params.getPathParam(1)).isEqualTo("") + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponseTest.kt index ab202a17..78017764 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeDatasetResponseTest.kt @@ -5,7 +5,7 @@ package com.braintrustdata.api.models import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class SummarizeDatasetResponseTest { +internal class SummarizeDatasetResponseTest { @Test fun createSummarizeDatasetResponse() { @@ -15,7 +15,7 @@ class SummarizeDatasetResponseTest { .datasetUrl("https://example.com") .projectName("project_name") .projectUrl("https://example.com") - .dataSummary(DataSummary.builder().totalRecords(123L).build()) + .dataSummary(DataSummary.builder().totalRecords(0L).build()) .build() assertThat(summarizeDatasetResponse).isNotNull assertThat(summarizeDatasetResponse.datasetName()).isEqualTo("dataset_name") @@ -23,6 +23,6 @@ class SummarizeDatasetResponseTest { assertThat(summarizeDatasetResponse.projectName()).isEqualTo("project_name") assertThat(summarizeDatasetResponse.projectUrl()).isEqualTo("https://example.com") assertThat(summarizeDatasetResponse.dataSummary()) - .contains(DataSummary.builder().totalRecords(123L).build()) + .contains(DataSummary.builder().totalRecords(0L).build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponseTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponseTest.kt index 75a79570..2b332170 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponseTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/SummarizeExperimentResponseTest.kt @@ -2,10 +2,11 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class SummarizeExperimentResponseTest { +internal class SummarizeExperimentResponseTest { @Test fun createSummarizeExperimentResponse() { @@ -16,8 +17,39 @@ class SummarizeExperimentResponseTest { .projectName("project_name") .projectUrl("https://example.com") .comparisonExperimentName("comparison_experiment_name") - .metrics(SummarizeExperimentResponse.Metrics.builder().build()) - .scores(SummarizeExperimentResponse.Scores.builder().build()) + .metrics( + SummarizeExperimentResponse.Metrics.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "improvements" to 0, + "metric" to 0, + "name" to "name", + "regressions" to 0, + "unit" to "unit", + "diff" to 0, + ) + ), + ) + .build() + ) + .scores( + SummarizeExperimentResponse.Scores.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "improvements" to 0, + "name" to "name", + "regressions" to 0, + "score" to 0, + "diff" to -1, + ) + ), + ) + .build() + ) .build() assertThat(summarizeExperimentResponse).isNotNull assertThat(summarizeExperimentResponse.experimentName()).isEqualTo("experiment_name") @@ -27,8 +59,39 @@ class SummarizeExperimentResponseTest { assertThat(summarizeExperimentResponse.comparisonExperimentName()) .contains("comparison_experiment_name") assertThat(summarizeExperimentResponse.metrics()) - .contains(SummarizeExperimentResponse.Metrics.builder().build()) + .contains( + SummarizeExperimentResponse.Metrics.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "improvements" to 0, + "metric" to 0, + "name" to "name", + "regressions" to 0, + "unit" to "unit", + "diff" to 0, + ) + ), + ) + .build() + ) assertThat(summarizeExperimentResponse.scores()) - .contains(SummarizeExperimentResponse.Scores.builder().build()) + .contains( + SummarizeExperimentResponse.Scores.builder() + .putAdditionalProperty( + "foo", + JsonValue.from( + mapOf( + "improvements" to 0, + "name" to "name", + "regressions" to 0, + "score" to 0, + "diff" to -1, + ) + ), + ) + .build() + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TaskTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TaskTest.kt deleted file mode 100644 index c8ec14d7..00000000 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TaskTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.braintrustdata.api.models - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class TaskTest { - - @Test - fun createTask() { - val task = Task.builder().type(Task.Type.TASK).build() - assertThat(task).isNotNull - assertThat(task.type()).isEqualTo(Task.Type.TASK) - } -} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParamsTest.kt index b059ced3..fa29626f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/TopLevelHelloWorldParamsTest.kt @@ -2,13 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.junit.jupiter.api.Test -class TopLevelHelloWorldParamsTest { +internal class TopLevelHelloWorldParamsTest { @Test - fun createTopLevelHelloWorldParams() { + fun create() { TopLevelHelloWorldParams.builder().build() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserListParamsTest.kt index 45d5d6ce..59ea68cd 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserListParamsTest.kt @@ -2,58 +2,63 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class UserListParamsTest { +internal class UserListParamsTest { @Test - fun createUserListParams() { + fun create() { UserListParams.builder() - .email(UserListParams.Email.ofString("string")) + .email("string") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .familyName(UserListParams.FamilyName.ofString("string")) - .givenName(UserListParams.GivenName.ofString("string")) - .ids(UserListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .familyName("string") + .givenName("string") + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = UserListParams.builder() - .email(UserListParams.Email.ofString("string")) + .email("string") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .familyName(UserListParams.FamilyName.ofString("string")) - .givenName(UserListParams.GivenName.ofString("string")) - .ids(UserListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .familyName("string") + .givenName("string") + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .orgName("org_name") .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() - val expected = mutableMapOf>() - expected.put("email", listOf(UserListParams.Email.ofString("string").toString())) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("family_name", listOf(UserListParams.FamilyName.ofString("string").toString())) - expected.put("given_name", listOf(UserListParams.GivenName.ofString("string").toString())) - expected.put( - "ids", - listOf(UserListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("org_name", listOf("org_name")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("email", "string") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("family_name", "string") + .put("given_name", "string") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("org_name", "org_name") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = UserListParams.builder().build() - val expected = mutableMapOf>() - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserRetrieveParamsTest.kt index ee03a0d3..6c4f828f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserRetrieveParamsTest.kt @@ -2,14 +2,13 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class UserRetrieveParamsTest { +internal class UserRetrieveParamsTest { @Test - fun createUserRetrieveParams() { + fun create() { UserRetrieveParams.builder().userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserTest.kt index fe6f4802..56a1074a 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/UserTest.kt @@ -6,7 +6,7 @@ import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class UserTest { +internal class UserTest { @Test fun createUser() { diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewCreateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewCreateParamsTest.kt index 931b25d4..c237c2ce 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewCreateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewCreateParamsTest.kt @@ -2,27 +2,38 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewCreateParamsTest { +internal class ViewCreateParamsTest { @Test - fun createViewCreateParams() { + fun create() { ViewCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewCreateParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -30,10 +41,10 @@ class ViewCreateParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -42,19 +53,30 @@ class ViewCreateParamsTest { } @Test - fun getBody() { + fun body() { val params = ViewCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewCreateParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -62,40 +84,53 @@ class ViewCreateParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewCreateParams.ObjectType.ORGANIZATION) - assertThat(body.viewType()).isEqualTo(ViewCreateParams.ViewType.PROJECTS) - assertThat(body.deletedAt()).isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.viewType()).contains(ViewCreateParams.ViewType.PROJECTS) + assertThat(body.deletedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(body.options()) - .isEqualTo( + .contains( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) - assertThat(body.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.viewData()) - .isEqualTo( + .contains( ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -103,17 +138,21 @@ class ViewCreateParamsTest { } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ViewCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) + .viewType(ViewCreateParams.ViewType.PROJECTS) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewCreateParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.viewType()).contains(ViewCreateParams.ViewType.PROJECTS) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataSearchTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataSearchTest.kt index beb70915..bd1ce88f 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataSearchTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataSearchTest.kt @@ -2,25 +2,28 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewDataSearchTest { +internal class ViewDataSearchTest { @Test fun createViewDataSearch() { val viewDataSearch = ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() assertThat(viewDataSearch).isNotNull - assertThat(viewDataSearch.filter().get()).containsExactly(JsonNull.of()) - assertThat(viewDataSearch.match().get()).containsExactly(JsonNull.of()) - assertThat(viewDataSearch.sort().get()).containsExactly(JsonNull.of()) - assertThat(viewDataSearch.tag().get()).containsExactly(JsonNull.of()) + assertThat(viewDataSearch.filter().get()) + .containsExactly(JsonValue.from(mapOf())) + assertThat(viewDataSearch.match().get()) + .containsExactly(JsonValue.from(mapOf())) + assertThat(viewDataSearch.sort().get()) + .containsExactly(JsonValue.from(mapOf())) + assertThat(viewDataSearch.tag().get()).containsExactly(JsonValue.from(mapOf())) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataTest.kt index ba16adf2..b1dabd9e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDataTest.kt @@ -2,11 +2,11 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewDataTest { +internal class ViewDataTest { @Test fun createViewData() { @@ -14,10 +14,10 @@ class ViewDataTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -25,10 +25,10 @@ class ViewDataTest { assertThat(viewData.search()) .contains( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDeleteParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDeleteParamsTest.kt index 76883050..6d6c784c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDeleteParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewDeleteParamsTest.kt @@ -2,47 +2,51 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewDeleteParamsTest { +internal class ViewDeleteParamsTest { @Test - fun createViewDeleteParams() { + fun create() { ViewDeleteParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() } @Test - fun getBody() { + fun body() { val params = ViewDeleteParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewDeleteParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ViewDeleteParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewDeleteParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) } @Test @@ -51,7 +55,7 @@ class ViewDeleteParamsTest { ViewDeleteParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() assertThat(params).isNotNull // path param "viewId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewListParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewListParamsTest.kt index 5b3094b1..05c283a8 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewListParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewListParamsTest.kt @@ -2,64 +2,73 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewListParamsTest { +internal class ViewListParamsTest { @Test - fun createViewListParams() { + fun create() { ViewListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ViewListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .viewName("view_name") - .viewType(ViewListParams.ViewType.PROJECTS) + .viewType(ViewType.PROJECTS) .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = ViewListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .ids(ViewListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .viewName("view_name") - .viewType(ViewListParams.ViewType.PROJECTS) + .viewType(ViewType.PROJECTS) .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(ViewListParams.ObjectType.ORGANIZATION.toString())) - expected.put("ending_before", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put( - "ids", - listOf(ViewListParams.Ids.ofString("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").toString()) - ) - expected.put("limit", listOf("123")) - expected.put("starting_after", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("view_name", listOf("view_name")) - expected.put("view_type", listOf(ViewListParams.ViewType.PROJECTS.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ids", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("limit", "0") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("view_name", "view_name") + .put("view_type", "projects") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ViewListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(ViewListParams.ObjectType.ORGANIZATION.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .build() + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewOptionsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewOptionsTest.kt index 7aea4ce7..1c0aceec 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewOptionsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewOptionsTest.kt @@ -2,23 +2,47 @@ package com.braintrustdata.api.models +import com.braintrustdata.api.core.JsonValue import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewOptionsTest { +internal class ViewOptionsTest { @Test fun createViewOptions() { val viewOptions = ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() assertThat(viewOptions).isNotNull assertThat(viewOptions.columnOrder().get()).containsExactly("string") - assertThat(viewOptions.columnSizing()).contains(ViewOptions.ColumnSizing.builder().build()) + assertThat(viewOptions.columnSizing()) + .contains( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) assertThat(viewOptions.columnVisibility()) - .contains(ViewOptions.ColumnVisibility.builder().build()) + .contains( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + assertThat(viewOptions.grouping()).contains("grouping") + assertThat(viewOptions.layout()).contains("layout") + assertThat(viewOptions.rowHeight()).contains("rowHeight") } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewReplaceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewReplaceParamsTest.kt index 6162d192..6dd1cd82 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewReplaceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewReplaceParamsTest.kt @@ -2,27 +2,38 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewReplaceParamsTest { +internal class ViewReplaceParamsTest { @Test - fun createViewReplaceParams() { + fun create() { ViewReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewReplaceParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewReplaceParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -30,10 +41,10 @@ class ViewReplaceParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -42,19 +53,30 @@ class ViewReplaceParamsTest { } @Test - fun getBody() { + fun body() { val params = ViewReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewReplaceParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewReplaceParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -62,40 +84,53 @@ class ViewReplaceParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewReplaceParams.ObjectType.ORGANIZATION) - assertThat(body.viewType()).isEqualTo(ViewReplaceParams.ViewType.PROJECTS) - assertThat(body.deletedAt()).isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.viewType()).contains(ViewReplaceParams.ViewType.PROJECTS) + assertThat(body.deletedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(body.options()) - .isEqualTo( + .contains( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) - assertThat(body.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.viewData()) - .isEqualTo( + .contains( ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -103,17 +138,21 @@ class ViewReplaceParamsTest { } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ViewReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewReplaceParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) + .viewType(ViewReplaceParams.ViewType.PROJECTS) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.name()).isEqualTo("name") assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewReplaceParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.viewType()).contains(ViewReplaceParams.ViewType.PROJECTS) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewRetrieveParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewRetrieveParamsTest.kt index c381863a..d73a583b 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewRetrieveParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewRetrieveParamsTest.kt @@ -2,47 +2,59 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.http.QueryParams import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewRetrieveParamsTest { +internal class ViewRetrieveParamsTest { @Test - fun createViewRetrieveParams() { + fun create() { ViewRetrieveParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewRetrieveParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() } @Test - fun getQueryParams() { + fun queryParams() { val params = ViewRetrieveParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewRetrieveParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(ViewRetrieveParams.ObjectType.ORGANIZATION.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .build() + ) } @Test - fun getQueryParamsWithoutOptionalFields() { + fun queryParamsWithoutOptionalFields() { val params = ViewRetrieveParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewRetrieveParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val expected = mutableMapOf>() - expected.put("object_id", listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - expected.put("object_type", listOf(ViewRetrieveParams.ObjectType.ORGANIZATION.toString())) - assertThat(params.getQueryParams()).isEqualTo(expected) + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("object_id", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("object_type", "organization") + .build() + ) } @Test @@ -51,7 +63,7 @@ class ViewRetrieveParamsTest { ViewRetrieveParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewRetrieveParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() assertThat(params).isNotNull // path param "viewId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewTest.kt index ce897144..e8ba2a61 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewTest.kt @@ -2,12 +2,12 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull +import com.braintrustdata.api.core.JsonValue import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewTest { +internal class ViewTest { @Test fun createView() { @@ -16,15 +16,26 @@ class ViewTest { .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(View.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(View.ViewType.PROJECTS) .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -32,10 +43,10 @@ class ViewTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -45,16 +56,27 @@ class ViewTest { assertThat(view.id()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(view.name()).isEqualTo("name") assertThat(view.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(view.objectType()).isEqualTo(View.ObjectType.ORGANIZATION) + assertThat(view.objectType()).isEqualTo(AclObjectType.ORGANIZATION) assertThat(view.viewType()).contains(View.ViewType.PROJECTS) assertThat(view.created()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(view.deletedAt()).contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) assertThat(view.options()) .contains( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) assertThat(view.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -63,10 +85,10 @@ class ViewTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewUpdateParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewUpdateParamsTest.kt index bfed15c2..36044079 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewUpdateParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/models/ViewUpdateParamsTest.kt @@ -2,25 +2,36 @@ package com.braintrustdata.api.models -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import kotlin.test.assertNotNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -class ViewUpdateParamsTest { +internal class ViewUpdateParamsTest { @Test - fun createViewUpdateParams() { + fun create() { ViewUpdateParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewUpdateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .name("name") .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -28,10 +39,10 @@ class ViewUpdateParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -41,18 +52,29 @@ class ViewUpdateParamsTest { } @Test - fun getBody() { + fun body() { val params = ViewUpdateParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewUpdateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .name("name") .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -60,58 +82,73 @@ class ViewUpdateParamsTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) .viewType(ViewUpdateParams.ViewType.PROJECTS) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewUpdateParams.ObjectType.ORGANIZATION) - assertThat(body.name()).isEqualTo("name") + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) + assertThat(body.name()).contains("name") assertThat(body.options()) - .isEqualTo( + .contains( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) - assertThat(body.userId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(body.userId()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.viewData()) - .isEqualTo( + .contains( ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) - assertThat(body.viewType()).isEqualTo(ViewUpdateParams.ViewType.PROJECTS) + assertThat(body.viewType()).contains(ViewUpdateParams.ViewType.PROJECTS) } @Test - fun getBodyWithoutOptionalFields() { + fun bodyWithoutOptionalFields() { val params = ViewUpdateParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewUpdateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() - val body = params.getBody() - assertThat(body).isNotNull + + val body = params._body() + + assertNotNull(body) assertThat(body.objectId()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(body.objectType()).isEqualTo(ViewUpdateParams.ObjectType.ORGANIZATION) + assertThat(body.objectType()).isEqualTo(AclObjectType.ORGANIZATION) } @Test @@ -120,7 +157,7 @@ class ViewUpdateParamsTest { ViewUpdateParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewUpdateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() assertThat(params).isNotNull // path param "viewId" diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ErrorHandlingTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ErrorHandlingTest.kt index 58a2b8f5..2716a7ab 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ErrorHandlingTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ErrorHandlingTest.kt @@ -4,7 +4,8 @@ package com.braintrustdata.api.services import com.braintrustdata.api.client.BraintrustClient import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonString +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.core.http.Headers import com.braintrustdata.api.core.jsonMapper import com.braintrustdata.api.errors.BadRequestException import com.braintrustdata.api.errors.BraintrustError @@ -16,33 +17,37 @@ import com.braintrustdata.api.errors.RateLimitException import com.braintrustdata.api.errors.UnauthorizedException import com.braintrustdata.api.errors.UnexpectedStatusCodeException import com.braintrustdata.api.errors.UnprocessableEntityException -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.databind.json.JsonMapper +import com.braintrustdata.api.models.ProjectCreateParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl -import com.github.tomakehurst.wiremock.client.WireMock.get -import com.github.tomakehurst.wiremock.client.WireMock.ok import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.status import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest -import com.google.common.collect.ImmutableListMultimap -import com.google.common.collect.ListMultimap -import java.time.OffsetDateTime import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.assertThatThrownBy -import org.assertj.core.api.InstanceOfAssertFactories -import org.assertj.guava.api.Assertions.assertThat +import org.assertj.core.api.Assertions.entry import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows @WireMockTest -class ErrorHandlingTest { +internal class ErrorHandlingTest { - private val JSON_MAPPER: JsonMapper = jsonMapper() + companion object { - private val BRAINTRUST_ERROR: BraintrustError = - BraintrustError.builder().putAdditionalProperty("key", JsonString.of("value")).build() + private val ERROR: BraintrustError = + BraintrustError.builder() + .putAdditionalProperty("errorProperty", JsonValue.from("42")) + .build() + + private val ERROR_JSON: ByteArray = jsonMapper().writeValueAsBytes(ERROR) + + private const val HEADER_NAME: String = "Error-Header" + + private const val HEADER_VALUE: String = "42" + + private const val NOT_JSON: String = "Not JSON" + } private lateinit var client: BraintrustClient @@ -50,306 +55,191 @@ class ErrorHandlingTest { fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { client = BraintrustOkHttpClient.builder() - .baseUrl(wmRuntimeInfo.getHttpBaseUrl()) + .baseUrl(wmRuntimeInfo.httpBaseUrl) .apiKey("My API Key") .build() } - @Test - fun projectsCreate200() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - - val expected = - Project.builder() - .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .name("name") - .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - - stubFor(post(anyUrl()).willReturn(ok().withBody(toJson(expected)))) - - assertThat(client.projects().create(params)).isEqualTo(expected) - } - @Test fun projectsCreate400() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(400).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(400).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertBadRequest(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(400) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate401() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(401).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(401).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertUnauthorized(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(401) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate403() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(403).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(403).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertPermissionDenied(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(403) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate404() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(404).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(404).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertNotFound(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(404) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate422() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(422).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(422).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertUnprocessableEntity( - e, - ImmutableListMultimap.of("Foo", "Bar"), - BRAINTRUST_ERROR + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() ) - }) + } + + assertThat(e.statusCode()).isEqualTo(422) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate429() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(429).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(429).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertRateLimit(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(429) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test fun projectsCreate500() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(500).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(500).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertInternalServer(e, ImmutableListMultimap.of("Foo", "Bar"), BRAINTRUST_ERROR) - }) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } + + assertThat(e.statusCode()).isEqualTo(500) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test - fun unexpectedStatusCode() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - + fun projectsCreate999() { + val projectService = client.projects() stubFor( post(anyUrl()) - .willReturn(status(999).withHeader("Foo", "Bar").withBody(toJson(BRAINTRUST_ERROR))) + .willReturn(status(999).withHeader(HEADER_NAME, HEADER_VALUE).withBody(ERROR_JSON)) ) - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertUnexpectedStatusCodeException( - e, - 999, - ImmutableListMultimap.of("Foo", "Bar"), - toJson(BRAINTRUST_ERROR) + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() ) - }) - } - - @Test - fun invalidBody() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - - stubFor(post(anyUrl()).willReturn(status(200).withBody("Not JSON"))) + } - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertThat(e) - .isInstanceOf(BraintrustException::class.java) - .hasMessage("Error reading response") - }) + assertThat(e.statusCode()).isEqualTo(999) + assertThat(e.error()).isEqualTo(ERROR) + assertThat(e.headers().toMap()).contains(entry(HEADER_NAME, listOf(HEADER_VALUE))) } @Test - fun invalidErrorBody() { - val params = ProjectCreateParams.builder().name("name").orgName("org_name").build() - - stubFor(post(anyUrl()).willReturn(status(400).withBody("Not JSON"))) - - assertThatThrownBy({ client.projects().create(params) }) - .satisfies({ e -> - assertBadRequest(e, ImmutableListMultimap.of(), BraintrustError.builder().build()) - }) - } - - private fun toJson(body: T): ByteArray { - return JSON_MAPPER.writeValueAsBytes(body) - } - - private fun assertUnexpectedStatusCodeException( - throwable: Throwable, - statusCode: Int, - headers: ListMultimap, - responseBody: ByteArray - ) { - assertThat(throwable) - .asInstanceOf( - InstanceOfAssertFactories.throwable(UnexpectedStatusCodeException::class.java) - ) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(statusCode) - assertThat(e.body()).isEqualTo(String(responseBody)) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } - - private fun assertBadRequest( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf(InstanceOfAssertFactories.throwable(BadRequestException::class.java)) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(400) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } - - private fun assertUnauthorized( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf(InstanceOfAssertFactories.throwable(UnauthorizedException::class.java)) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(401) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } - - private fun assertPermissionDenied( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf( - InstanceOfAssertFactories.throwable(PermissionDeniedException::class.java) - ) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(403) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } - - private fun assertNotFound( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf(InstanceOfAssertFactories.throwable(NotFoundException::class.java)) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(404) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } + fun projectsCreateInvalidJsonBody() { + val projectService = client.projects() + stubFor( + post(anyUrl()) + .willReturn(status(200).withHeader(HEADER_NAME, HEADER_VALUE).withBody(NOT_JSON)) + ) - private fun assertUnprocessableEntity( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf( - InstanceOfAssertFactories.throwable(UnprocessableEntityException::class.java) - ) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(422) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } + val e = + assertThrows { + projectService.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + } - private fun assertRateLimit( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf(InstanceOfAssertFactories.throwable(RateLimitException::class.java)) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(429) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) + assertThat(e).hasMessage("Error reading response") } - private fun assertInternalServer( - throwable: Throwable, - headers: ListMultimap, - error: BraintrustError - ) { - assertThat(throwable) - .asInstanceOf(InstanceOfAssertFactories.throwable(InternalServerException::class.java)) - .satisfies({ e -> - assertThat(e.statusCode()).isEqualTo(500) - assertThat(e.error()).isEqualTo(error) - assertThat(e.headers()).containsAllEntriesOf(headers) - }) - } + private fun Headers.toMap(): Map> = + mutableMapOf>().also { map -> + names().forEach { map[it] = values(it) } + } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ServiceParamsTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ServiceParamsTest.kt index d1c75949..9e25370e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ServiceParamsTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/ServiceParamsTest.kt @@ -4,31 +4,23 @@ package com.braintrustdata.api.services import com.braintrustdata.api.client.BraintrustClient import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonString import com.braintrustdata.api.core.JsonValue -import com.braintrustdata.api.core.jsonMapper -import com.braintrustdata.api.models.* -import com.fasterxml.jackson.databind.json.JsonMapper +import com.braintrustdata.api.models.ProjectCreateParams import com.github.tomakehurst.wiremock.client.WireMock.anyUrl import com.github.tomakehurst.wiremock.client.WireMock.equalTo -import com.github.tomakehurst.wiremock.client.WireMock.get import com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath import com.github.tomakehurst.wiremock.client.WireMock.ok import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor -import com.github.tomakehurst.wiremock.client.WireMock.put import com.github.tomakehurst.wiremock.client.WireMock.stubFor import com.github.tomakehurst.wiremock.client.WireMock.verify import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest -import java.time.OffsetDateTime import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @WireMockTest -class ServiceParamsTest { - - private val JSON_MAPPER: JsonMapper = jsonMapper() +internal class ServiceParamsTest { private lateinit var client: BraintrustClient @@ -36,55 +28,31 @@ class ServiceParamsTest { fun beforeEach(wmRuntimeInfo: WireMockRuntimeInfo) { client = BraintrustOkHttpClient.builder() + .baseUrl(wmRuntimeInfo.httpBaseUrl) .apiKey("My API Key") - .baseUrl(wmRuntimeInfo.getHttpBaseUrl()) .build() } @Test - fun projectsCreateWithAdditionalParams() { - val additionalHeaders = mutableMapOf>() - - additionalHeaders.put("x-test-header", listOf("abc1234")) - - val additionalQueryParams = mutableMapOf>() - - additionalQueryParams.put("test_query_param", listOf("def567")) - - val additionalBodyProperties = mutableMapOf() - - additionalBodyProperties.put("testBodyProperty", JsonString.of("ghi890")) + fun create() { + val projectService = client.projects() + stubFor(post(anyUrl()).willReturn(ok("{}"))) - val params = + projectService.create( ProjectCreateParams.builder() - .name("name") + .name("x") .orgName("org_name") - .additionalHeaders(additionalHeaders) - .additionalBodyProperties(additionalBodyProperties) - .additionalQueryParams(additionalQueryParams) + .putAdditionalHeader("Secret-Header", "42") + .putAdditionalQueryParam("secret_query_param", "42") + .putAdditionalBodyProperty("secretProperty", JsonValue.from("42")) .build() - - val apiResponse = - Project.builder() - .id("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .name("name") - .orgId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - - stubFor( - post(anyUrl()) - .withHeader("x-test-header", equalTo("abc1234")) - .withQueryParam("test_query_param", equalTo("def567")) - .withRequestBody(matchingJsonPath("$.testBodyProperty", equalTo("ghi890"))) - .willReturn(ok(JSON_MAPPER.writeValueAsString(apiResponse))) ) - client.projects().create(params) - - verify(postRequestedFor(anyUrl())) + verify( + postRequestedFor(anyUrl()) + .withHeader("Secret-Header", equalTo("42")) + .withQueryParam("secret_query_param", equalTo("42")) + .withRequestBody(matchingJsonPath("$.secretProperty", equalTo("42"))) + ) } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncTest.kt new file mode 100644 index 00000000..97eca503 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AclServiceAsyncTest.kt @@ -0,0 +1,170 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.AclBatchUpdateParams +import com.braintrustdata.api.models.AclCreateParams +import com.braintrustdata.api.models.AclDeleteParams +import com.braintrustdata.api.models.AclFindAndDeleteParams +import com.braintrustdata.api.models.AclListParams +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.AclRetrieveParams +import com.braintrustdata.api.models.Permission +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AclServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val aclFuture = + aclServiceAsync.create( + AclCreateParams.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val acl = aclFuture.get() + acl.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val aclFuture = + aclServiceAsync.retrieve( + AclRetrieveParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val acl = aclFuture.get() + acl.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val pageFuture = + aclServiceAsync.list( + AclListParams.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .build() + ) + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val aclFuture = + aclServiceAsync.delete( + AclDeleteParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val acl = aclFuture.get() + acl.validate() + } + + @Test + fun batchUpdate() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val aclBatchUpdateResponseFuture = + aclServiceAsync.batchUpdate( + AclBatchUpdateParams.builder() + .addAddAcl( + AclBatchUpdateParams.AddAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + .addRemoveAcl( + AclBatchUpdateParams.RemoveAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + .build() + ) + + val aclBatchUpdateResponse = aclBatchUpdateResponseFuture.get() + aclBatchUpdateResponse.validate() + } + + @Test + fun findAndDelete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aclServiceAsync = client.acls() + + val aclFuture = + aclServiceAsync.findAndDelete( + AclFindAndDeleteParams.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val acl = aclFuture.get() + acl.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncTest.kt new file mode 100644 index 00000000..f9dd58e3 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/AiSecretServiceAsyncTest.kt @@ -0,0 +1,176 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AiSecretCreateParams +import com.braintrustdata.api.models.AiSecretDeleteParams +import com.braintrustdata.api.models.AiSecretFindAndDeleteParams +import com.braintrustdata.api.models.AiSecretReplaceParams +import com.braintrustdata.api.models.AiSecretRetrieveParams +import com.braintrustdata.api.models.AiSecretUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AiSecretServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.create( + AiSecretCreateParams.builder() + .name("name") + .metadata( + AiSecretCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .orgName("org_name") + .secret("secret") + .type("type") + .build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.retrieve( + AiSecretRetrieveParams.builder() + .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.update( + AiSecretUpdateParams.builder() + .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .metadata( + AiSecretUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("name") + .secret("secret") + .type("type") + .build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val pageFuture = aiSecretServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.delete( + AiSecretDeleteParams.builder() + .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } + + @Test + fun findAndDelete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.findAndDelete( + AiSecretFindAndDeleteParams.builder().name("name").orgName("org_name").build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val aiSecretServiceAsync = client.aiSecrets() + + val aISecretFuture = + aiSecretServiceAsync.replace( + AiSecretReplaceParams.builder() + .name("name") + .metadata( + AiSecretReplaceParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .orgName("org_name") + .secret("secret") + .type("type") + .build() + ) + + val aISecret = aISecretFuture.get() + aISecret.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncTest.kt new file mode 100644 index 00000000..71d9172a --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ApiKeyServiceAsyncTest.kt @@ -0,0 +1,88 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.ApiKeyCreateParams +import com.braintrustdata.api.models.ApiKeyDeleteParams +import com.braintrustdata.api.models.ApiKeyRetrieveParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ApiKeyServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val apiKeyServiceAsync = client.apiKeys() + + val createApiKeyOutputFuture = + apiKeyServiceAsync.create( + ApiKeyCreateParams.builder().name("name").orgName("org_name").build() + ) + + val createApiKeyOutput = createApiKeyOutputFuture.get() + createApiKeyOutput.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val apiKeyServiceAsync = client.apiKeys() + + val apiKeyFuture = + apiKeyServiceAsync.retrieve( + ApiKeyRetrieveParams.builder() + .apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val apiKey = apiKeyFuture.get() + apiKey.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val apiKeyServiceAsync = client.apiKeys() + + val pageFuture = apiKeyServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val apiKeyServiceAsync = client.apiKeys() + + val apiKeyFuture = + apiKeyServiceAsync.delete( + ApiKeyDeleteParams.builder() + .apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val apiKey = apiKeyFuture.get() + apiKey.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncTest.kt new file mode 100644 index 00000000..dba276c4 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/DatasetServiceAsyncTest.kt @@ -0,0 +1,284 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.DatasetCreateParams +import com.braintrustdata.api.models.DatasetDeleteParams +import com.braintrustdata.api.models.DatasetFeedbackParams +import com.braintrustdata.api.models.DatasetFetchParams +import com.braintrustdata.api.models.DatasetFetchPostParams +import com.braintrustdata.api.models.DatasetInsertParams +import com.braintrustdata.api.models.DatasetRetrieveParams +import com.braintrustdata.api.models.DatasetSummarizeParams +import com.braintrustdata.api.models.DatasetUpdateParams +import com.braintrustdata.api.models.FeedbackDatasetItem +import com.braintrustdata.api.models.InsertDatasetEvent +import com.braintrustdata.api.models.ObjectReference +import java.time.OffsetDateTime +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class DatasetServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val datasetFuture = + datasetServiceAsync.create( + DatasetCreateParams.builder() + .name("x") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .metadata( + DatasetCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + + val dataset = datasetFuture.get() + dataset.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val datasetFuture = + datasetServiceAsync.retrieve( + DatasetRetrieveParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val dataset = datasetFuture.get() + dataset.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val datasetFuture = + datasetServiceAsync.update( + DatasetUpdateParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .metadata( + DatasetUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("name") + .build() + ) + + val dataset = datasetFuture.get() + dataset.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val pageFuture = datasetServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val datasetFuture = + datasetServiceAsync.delete( + DatasetDeleteParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val dataset = datasetFuture.get() + dataset.validate() + } + + @Test + fun feedback() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val feedbackResponseSchemaFuture = + datasetServiceAsync.feedback( + DatasetFeedbackParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addFeedback( + FeedbackDatasetItem.builder() + .id("id") + .comment("comment") + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .source(FeedbackDatasetItem.Source.APP) + .addTag("string") + .build() + ) + .build() + ) + + val feedbackResponseSchema = feedbackResponseSchemaFuture.get() + feedbackResponseSchema.validate() + } + + @Test + fun fetch() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val fetchDatasetEventsResponseFuture = + datasetServiceAsync.fetch( + DatasetFetchParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchDatasetEventsResponse = fetchDatasetEventsResponseFuture.get() + fetchDatasetEventsResponse.validate() + } + + @Test + fun fetchPost() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val fetchDatasetEventsResponseFuture = + datasetServiceAsync.fetchPost( + DatasetFetchPostParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .cursor("cursor") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchDatasetEventsResponse = fetchDatasetEventsResponseFuture.get() + fetchDatasetEventsResponse.validate() + } + + @Test + fun insert() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val insertEventsResponseFuture = + datasetServiceAsync.insert( + DatasetInsertParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addEvent( + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + ) + .build() + ) + + val insertEventsResponse = insertEventsResponseFuture.get() + insertEventsResponse.validate() + } + + @Test + fun summarize() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val datasetServiceAsync = client.datasets() + + val summarizeDatasetResponseFuture = + datasetServiceAsync.summarize( + DatasetSummarizeParams.builder() + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .summarizeData(true) + .build() + ) + + val summarizeDatasetResponse = summarizeDatasetResponseFuture.get() + summarizeDatasetResponse.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncTest.kt new file mode 100644 index 00000000..9d95d5e8 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EnvVarServiceAsyncTest.kt @@ -0,0 +1,151 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.EnvVarCreateParams +import com.braintrustdata.api.models.EnvVarDeleteParams +import com.braintrustdata.api.models.EnvVarListParams +import com.braintrustdata.api.models.EnvVarObjectType +import com.braintrustdata.api.models.EnvVarReplaceParams +import com.braintrustdata.api.models.EnvVarRetrieveParams +import com.braintrustdata.api.models.EnvVarUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class EnvVarServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.create( + EnvVarCreateParams.builder() + .name("name") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(EnvVarCreateParams.ObjectType.ORGANIZATION) + .value("value") + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.retrieve( + EnvVarRetrieveParams.builder() + .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.update( + EnvVarUpdateParams.builder() + .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .name("name") + .value("value") + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.list( + EnvVarListParams.builder() + .envVarName("env_var_name") + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(EnvVarObjectType.ORGANIZATION) + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.delete( + EnvVarDeleteParams.builder() + .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val envVarServiceAsync = client.envVars() + + val envVarFuture = + envVarServiceAsync.replace( + EnvVarReplaceParams.builder() + .name("name") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(EnvVarReplaceParams.ObjectType.ORGANIZATION) + .value("value") + .build() + ) + + val envVar = envVarFuture.get() + envVar.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncTest.kt new file mode 100644 index 00000000..965be9d0 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/EvalServiceAsyncTest.kt @@ -0,0 +1,110 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.EvalCreateParams +import com.braintrustdata.api.models.RepoInfo +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class EvalServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val evalServiceAsync = client.evals() + + val summarizeExperimentResponseFuture = + evalServiceAsync.create( + EvalCreateParams.builder() + .data( + EvalCreateParams.Data.DatasetId.builder() + .datasetId("dataset_id") + ._internalBtql( + EvalCreateParams.Data.DatasetId._InternalBtql + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .projectId("project_id") + .addScore( + EvalCreateParams.Score.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() + ) + .task( + EvalCreateParams.Task.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() + ) + .baseExperimentId("base_experiment_id") + .baseExperimentName("base_experiment_name") + .experimentName("experiment_name") + .gitMetadataSettings( + EvalCreateParams.GitMetadataSettings.builder() + .collect(EvalCreateParams.GitMetadataSettings.Collect.ALL) + .addField(EvalCreateParams.GitMetadataSettings.Field.COMMIT) + .build() + ) + .isPublic(true) + .maxConcurrency(0.0) + .metadata( + EvalCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .parent( + EvalCreateParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + EvalCreateParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + EvalCreateParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + EvalCreateParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) + .stream(true) + .timeout(0.0) + .trialCount(0.0) + .build() + ) + + val summarizeExperimentResponse = summarizeExperimentResponseFuture.get() + summarizeExperimentResponse.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncTest.kt new file mode 100644 index 00000000..854ef1dd --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ExperimentServiceAsyncTest.kt @@ -0,0 +1,360 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.ExperimentCreateParams +import com.braintrustdata.api.models.ExperimentDeleteParams +import com.braintrustdata.api.models.ExperimentFeedbackParams +import com.braintrustdata.api.models.ExperimentFetchParams +import com.braintrustdata.api.models.ExperimentFetchPostParams +import com.braintrustdata.api.models.ExperimentInsertParams +import com.braintrustdata.api.models.ExperimentRetrieveParams +import com.braintrustdata.api.models.ExperimentSummarizeParams +import com.braintrustdata.api.models.ExperimentUpdateParams +import com.braintrustdata.api.models.FeedbackExperimentItem +import com.braintrustdata.api.models.InsertExperimentEvent +import com.braintrustdata.api.models.ObjectReference +import com.braintrustdata.api.models.RepoInfo +import com.braintrustdata.api.models.SpanAttributes +import com.braintrustdata.api.models.SpanType +import java.time.OffsetDateTime +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ExperimentServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val experimentFuture = + experimentServiceAsync.create( + ExperimentCreateParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .baseExpId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .datasetVersion("dataset_version") + .description("description") + .ensureNew(true) + .metadata( + ExperimentCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("x") + .public_(true) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) + .build() + ) + + val experiment = experimentFuture.get() + experiment.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val experimentFuture = + experimentServiceAsync.retrieve( + ExperimentRetrieveParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val experiment = experimentFuture.get() + experiment.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val experimentFuture = + experimentServiceAsync.update( + ExperimentUpdateParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .baseExpId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .datasetVersion("dataset_version") + .description("description") + .metadata( + ExperimentUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("name") + .public_(true) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) + .build() + ) + + val experiment = experimentFuture.get() + experiment.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val pageFuture = experimentServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val experimentFuture = + experimentServiceAsync.delete( + ExperimentDeleteParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val experiment = experimentFuture.get() + experiment.validate() + } + + @Test + fun feedback() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val feedbackResponseSchemaFuture = + experimentServiceAsync.feedback( + ExperimentFeedbackParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addFeedback( + FeedbackExperimentItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackExperimentItem.Source.APP) + .addTag("string") + .build() + ) + .build() + ) + + val feedbackResponseSchema = feedbackResponseSchemaFuture.get() + feedbackResponseSchema.validate() + } + + @Test + fun fetch() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val fetchExperimentEventsResponseFuture = + experimentServiceAsync.fetch( + ExperimentFetchParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchExperimentEventsResponse = fetchExperimentEventsResponseFuture.get() + fetchExperimentEventsResponse.validate() + } + + @Test + fun fetchPost() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val fetchExperimentEventsResponseFuture = + experimentServiceAsync.fetchPost( + ExperimentFetchPostParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .cursor("cursor") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchExperimentEventsResponse = fetchExperimentEventsResponseFuture.get() + fetchExperimentEventsResponse.validate() + } + + @Test + fun insert() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val insertEventsResponseFuture = + experimentServiceAsync.insert( + ExperimentInsertParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addEvent( + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata( + InsertExperimentEvent.Metadata.builder().model("model").build() + ) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + ) + .build() + ) + + val insertEventsResponse = insertEventsResponseFuture.get() + insertEventsResponse.validate() + } + + @Test + fun summarize() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val experimentServiceAsync = client.experiments() + + val summarizeExperimentResponseFuture = + experimentServiceAsync.summarize( + ExperimentSummarizeParams.builder() + .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .summarizeScores(true) + .build() + ) + + val summarizeExperimentResponse = summarizeExperimentResponseFuture.get() + summarizeExperimentResponse.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncTest.kt new file mode 100644 index 00000000..74787883 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/FunctionServiceAsyncTest.kt @@ -0,0 +1,497 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.FunctionCreateParams +import com.braintrustdata.api.models.FunctionDeleteParams +import com.braintrustdata.api.models.FunctionInvokeParams +import com.braintrustdata.api.models.FunctionReplaceParams +import com.braintrustdata.api.models.FunctionRetrieveParams +import com.braintrustdata.api.models.FunctionUpdateParams +import com.braintrustdata.api.models.PromptData +import com.braintrustdata.api.models.PromptOptions +import kotlin.jvm.optionals.getOrNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class FunctionServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val functionFuture = + functionServiceAsync.create( + FunctionCreateParams.builder() + .functionData( + FunctionCreateParams.FunctionData.Prompt.builder() + .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) + .build() + ) + .name("x") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .slug("x") + .description("description") + .functionSchema( + FunctionCreateParams.FunctionSchema.builder() + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) + .build() + ) + .functionType(FunctionCreateParams.FunctionType.LLM) + .origin( + FunctionCreateParams.Origin.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .internal_(true) + .build() + ) + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .addTag("string") + .build() + ) + + val function = functionFuture.get() + function.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val functionFuture = + functionServiceAsync.retrieve( + FunctionRetrieveParams.builder() + .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val function = functionFuture.get() + function.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val functionFuture = + functionServiceAsync.update( + FunctionUpdateParams.builder() + .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .functionData( + FunctionUpdateParams.FunctionData.Prompt.builder() + .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) + .build() + ) + .name("name") + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .addTag("string") + .build() + ) + + val function = functionFuture.get() + function.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val pageFuture = functionServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val functionFuture = + functionServiceAsync.delete( + FunctionDeleteParams.builder() + .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val function = functionFuture.get() + function.validate() + } + + @Test + fun invoke() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val responseFuture = + functionServiceAsync.invoke( + FunctionInvokeParams.builder() + .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .addMessage( + FunctionInvokeParams.Message.System.builder() + .role(FunctionInvokeParams.Message.System.Role.SYSTEM) + .content("content") + .name("name") + .build() + ) + .metadata( + FunctionInvokeParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .mode(FunctionInvokeParams.Mode.AUTO) + .parent( + FunctionInvokeParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + FunctionInvokeParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + FunctionInvokeParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .stream(true) + .version("version") + .build() + ) + + val response = responseFuture.get() + val unwrappedResponse = response.getOrNull() + unwrappedResponse?.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val functionServiceAsync = client.functions() + + val functionFuture = + functionServiceAsync.replace( + FunctionReplaceParams.builder() + .functionData( + FunctionReplaceParams.FunctionData.Prompt.builder() + .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) + .build() + ) + .name("x") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .slug("x") + .description("description") + .functionSchema( + FunctionReplaceParams.FunctionSchema.builder() + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) + .build() + ) + .functionType(FunctionReplaceParams.FunctionType.LLM) + .origin( + FunctionReplaceParams.Origin.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .internal_(true) + .build() + ) + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .addTag("string") + .build() + ) + + val function = functionFuture.get() + function.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncTest.kt new file mode 100644 index 00000000..5b8f2e23 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/GroupServiceAsyncTest.kt @@ -0,0 +1,144 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.GroupCreateParams +import com.braintrustdata.api.models.GroupDeleteParams +import com.braintrustdata.api.models.GroupReplaceParams +import com.braintrustdata.api.models.GroupRetrieveParams +import com.braintrustdata.api.models.GroupUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class GroupServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val groupFuture = + groupServiceAsync.create( + GroupCreateParams.builder() + .name("x") + .description("description") + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .orgName("org_name") + .build() + ) + + val group = groupFuture.get() + group.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val groupFuture = + groupServiceAsync.retrieve( + GroupRetrieveParams.builder() + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val group = groupFuture.get() + group.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val groupFuture = + groupServiceAsync.update( + GroupUpdateParams.builder() + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("x") + .addRemoveMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addRemoveMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val group = groupFuture.get() + group.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val pageFuture = groupServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val groupFuture = + groupServiceAsync.delete( + GroupDeleteParams.builder().groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val group = groupFuture.get() + group.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val groupServiceAsync = client.groups() + + val groupFuture = + groupServiceAsync.replace( + GroupReplaceParams.builder() + .name("x") + .description("description") + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .orgName("org_name") + .build() + ) + + val group = groupFuture.get() + group.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncTest.kt new file mode 100644 index 00000000..17e8d406 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/OrganizationServiceAsyncTest.kt @@ -0,0 +1,95 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.OrganizationDeleteParams +import com.braintrustdata.api.models.OrganizationRetrieveParams +import com.braintrustdata.api.models.OrganizationUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class OrganizationServiceAsyncTest { + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val organizationServiceAsync = client.organizations() + + val organizationFuture = + organizationServiceAsync.retrieve( + OrganizationRetrieveParams.builder() + .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val organization = organizationFuture.get() + organization.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val organizationServiceAsync = client.organizations() + + val organizationFuture = + organizationServiceAsync.update( + OrganizationUpdateParams.builder() + .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .apiUrl("api_url") + .isUniversalApi(true) + .name("name") + .proxyUrl("proxy_url") + .realtimeUrl("realtime_url") + .build() + ) + + val organization = organizationFuture.get() + organization.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val organizationServiceAsync = client.organizations() + + val pageFuture = organizationServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val organizationServiceAsync = client.organizations() + + val organizationFuture = + organizationServiceAsync.delete( + OrganizationDeleteParams.builder() + .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val organization = organizationFuture.get() + organization.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncTest.kt new file mode 100644 index 00000000..cf9b25d3 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectScoreServiceAsyncTest.kt @@ -0,0 +1,211 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.OnlineScoreConfig +import com.braintrustdata.api.models.ProjectScoreCategory +import com.braintrustdata.api.models.ProjectScoreConfig +import com.braintrustdata.api.models.ProjectScoreCreateParams +import com.braintrustdata.api.models.ProjectScoreDeleteParams +import com.braintrustdata.api.models.ProjectScoreReplaceParams +import com.braintrustdata.api.models.ProjectScoreRetrieveParams +import com.braintrustdata.api.models.ProjectScoreType +import com.braintrustdata.api.models.ProjectScoreUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ProjectScoreServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val projectScoreFuture = + projectScoreServiceAsync.create( + ProjectScoreCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .scoreType(ProjectScoreType.SLIDER) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) + ) + .config( + ProjectScoreConfig.builder() + .destination("destination") + .multiSelect(true) + .online( + OnlineScoreConfig.builder() + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() + ) + .applyToRootSpan(true) + .addApplyToSpanName("string") + .build() + ) + .build() + ) + .description("description") + .build() + ) + + val projectScore = projectScoreFuture.get() + projectScore.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val projectScoreFuture = + projectScoreServiceAsync.retrieve( + ProjectScoreRetrieveParams.builder() + .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val projectScore = projectScoreFuture.get() + projectScore.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val projectScoreFuture = + projectScoreServiceAsync.update( + ProjectScoreUpdateParams.builder() + .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) + ) + .config( + ProjectScoreConfig.builder() + .destination("destination") + .multiSelect(true) + .online( + OnlineScoreConfig.builder() + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() + ) + .applyToRootSpan(true) + .addApplyToSpanName("string") + .build() + ) + .build() + ) + .description("description") + .name("name") + .scoreType(ProjectScoreType.SLIDER) + .build() + ) + + val projectScore = projectScoreFuture.get() + projectScore.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val pageFuture = projectScoreServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val projectScoreFuture = + projectScoreServiceAsync.delete( + ProjectScoreDeleteParams.builder() + .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val projectScore = projectScoreFuture.get() + projectScore.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectScoreServiceAsync = client.projectScores() + + val projectScoreFuture = + projectScoreServiceAsync.replace( + ProjectScoreReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .scoreType(ProjectScoreType.SLIDER) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) + ) + .config( + ProjectScoreConfig.builder() + .destination("destination") + .multiSelect(true) + .online( + OnlineScoreConfig.builder() + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() + ) + .applyToRootSpan(true) + .addApplyToSpanName("string") + .build() + ) + .build() + ) + .description("description") + .build() + ) + + val projectScore = projectScoreFuture.get() + projectScore.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncTest.kt new file mode 100644 index 00000000..79ae13f8 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectServiceAsyncTest.kt @@ -0,0 +1,125 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.ProjectCreateParams +import com.braintrustdata.api.models.ProjectDeleteParams +import com.braintrustdata.api.models.ProjectRetrieveParams +import com.braintrustdata.api.models.ProjectSettings +import com.braintrustdata.api.models.ProjectUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ProjectServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectServiceAsync = client.projects() + + val projectFuture = + projectServiceAsync.create( + ProjectCreateParams.builder().name("x").orgName("org_name").build() + ) + + val project = projectFuture.get() + project.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectServiceAsync = client.projects() + + val projectFuture = + projectServiceAsync.retrieve( + ProjectRetrieveParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val project = projectFuture.get() + project.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectServiceAsync = client.projects() + + val projectFuture = + projectServiceAsync.update( + ProjectUpdateParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .name("name") + .settings( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) + .build() + ) + + val project = projectFuture.get() + project.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectServiceAsync = client.projects() + + val pageFuture = projectServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectServiceAsync = client.projects() + + val projectFuture = + projectServiceAsync.delete( + ProjectDeleteParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val project = projectFuture.get() + project.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncTest.kt new file mode 100644 index 00000000..8f4ee746 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ProjectTagServiceAsyncTest.kt @@ -0,0 +1,141 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.ProjectTagCreateParams +import com.braintrustdata.api.models.ProjectTagDeleteParams +import com.braintrustdata.api.models.ProjectTagReplaceParams +import com.braintrustdata.api.models.ProjectTagRetrieveParams +import com.braintrustdata.api.models.ProjectTagUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ProjectTagServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val projectTagFuture = + projectTagServiceAsync.create( + ProjectTagCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .color("color") + .description("description") + .build() + ) + + val projectTag = projectTagFuture.get() + projectTag.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val projectTagFuture = + projectTagServiceAsync.retrieve( + ProjectTagRetrieveParams.builder() + .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val projectTag = projectTagFuture.get() + projectTag.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val projectTagFuture = + projectTagServiceAsync.update( + ProjectTagUpdateParams.builder() + .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .color("color") + .description("description") + .name("name") + .build() + ) + + val projectTag = projectTagFuture.get() + projectTag.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val pageFuture = projectTagServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val projectTagFuture = + projectTagServiceAsync.delete( + ProjectTagDeleteParams.builder() + .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val projectTag = projectTagFuture.get() + projectTag.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val projectTagServiceAsync = client.projectTags() + + val projectTagFuture = + projectTagServiceAsync.replace( + ProjectTagReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .color("color") + .description("description") + .build() + ) + + val projectTag = projectTagFuture.get() + projectTag.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncTest.kt new file mode 100644 index 00000000..2216c197 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/PromptServiceAsyncTest.kt @@ -0,0 +1,395 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.PromptCreateParams +import com.braintrustdata.api.models.PromptData +import com.braintrustdata.api.models.PromptDeleteParams +import com.braintrustdata.api.models.PromptOptions +import com.braintrustdata.api.models.PromptReplaceParams +import com.braintrustdata.api.models.PromptRetrieveParams +import com.braintrustdata.api.models.PromptUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class PromptServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val promptFuture = + promptServiceAsync.create( + PromptCreateParams.builder() + .name("x") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .slug("x") + .description("description") + .functionType(PromptCreateParams.FunctionType.LLM) + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .addTag("string") + .build() + ) + + val prompt = promptFuture.get() + prompt.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val promptFuture = + promptServiceAsync.retrieve( + PromptRetrieveParams.builder() + .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val prompt = promptFuture.get() + prompt.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val promptFuture = + promptServiceAsync.update( + PromptUpdateParams.builder() + .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("name") + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .slug("slug") + .addTag("string") + .build() + ) + + val prompt = promptFuture.get() + prompt.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val pageFuture = promptServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val promptFuture = + promptServiceAsync.delete( + PromptDeleteParams.builder() + .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val prompt = promptFuture.get() + prompt.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val promptServiceAsync = client.prompts() + + val promptFuture = + promptServiceAsync.replace( + PromptReplaceParams.builder() + .name("x") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .slug("x") + .description("description") + .functionType(PromptReplaceParams.FunctionType.LLM) + .promptData( + PromptData.builder() + .options( + PromptOptions.builder() + .model("model") + .params( + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() + ) + .position("position") + .build() + ) + .origin( + PromptData.Origin.builder() + .projectId("project_id") + .promptId("prompt_id") + .promptVersion("prompt_version") + .build() + ) + .parser( + PromptData.Parser.builder() + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .type(PromptData.Parser.Type.LLM_CLASSIFIER) + .useCot(true) + .build() + ) + .prompt( + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() + ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() + ) + .build() + ) + .addTag("string") + .build() + ) + + val prompt = promptFuture.get() + prompt.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncTest.kt new file mode 100644 index 00000000..45d60fc2 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/RoleServiceAsyncTest.kt @@ -0,0 +1,164 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.Permission +import com.braintrustdata.api.models.RoleCreateParams +import com.braintrustdata.api.models.RoleDeleteParams +import com.braintrustdata.api.models.RoleReplaceParams +import com.braintrustdata.api.models.RoleRetrieveParams +import com.braintrustdata.api.models.RoleUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class RoleServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val roleFuture = + roleServiceAsync.create( + RoleCreateParams.builder() + .name("x") + .description("description") + .addMemberPermission( + RoleCreateParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() + ) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .orgName("org_name") + .build() + ) + + val role = roleFuture.get() + role.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val roleFuture = + roleServiceAsync.retrieve( + RoleRetrieveParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val role = roleFuture.get() + role.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val roleFuture = + roleServiceAsync.update( + RoleUpdateParams.builder() + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberPermission( + RoleUpdateParams.AddMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() + ) + .addAddMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("x") + .addRemoveMemberPermission( + RoleUpdateParams.RemoveMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() + ) + .addRemoveMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val role = roleFuture.get() + role.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val pageFuture = roleServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val roleFuture = + roleServiceAsync.delete( + RoleDeleteParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val role = roleFuture.get() + role.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val roleServiceAsync = client.roles() + + val roleFuture = + roleServiceAsync.replace( + RoleReplaceParams.builder() + .name("x") + .description("description") + .addMemberPermission( + RoleReplaceParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() + ) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .orgName("org_name") + .build() + ) + + val role = roleFuture.get() + role.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncTest.kt new file mode 100644 index 00000000..7f3f4d1c --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/SpanIframeServiceAsyncTest.kt @@ -0,0 +1,144 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class SpanIframeServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val spanIFrameFuture = + spanIframeServiceAsync.create( + SpanIframeCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + ) + + val spanIFrame = spanIFrameFuture.get() + spanIFrame.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val spanIFrameFuture = + spanIframeServiceAsync.retrieve( + SpanIframeRetrieveParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val spanIFrame = spanIFrameFuture.get() + spanIFrame.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val spanIFrameFuture = + spanIframeServiceAsync.update( + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("name") + .postMessage(true) + .url("url") + .build() + ) + + val spanIFrame = spanIFrameFuture.get() + spanIFrame.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val pageFuture = spanIframeServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val spanIFrameFuture = + spanIframeServiceAsync.delete( + SpanIframeDeleteParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val spanIFrame = spanIFrameFuture.get() + spanIFrame.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeServiceAsync = client.spanIframes() + + val spanIFrameFuture = + spanIframeServiceAsync.replace( + SpanIframeReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + ) + + val spanIFrame = spanIFrameFuture.get() + spanIFrame.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncTest.kt new file mode 100644 index 00000000..08b3dbdf --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/TopLevelServiceAsyncTest.kt @@ -0,0 +1,26 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class TopLevelServiceAsyncTest { + + @Test + fun helloWorld() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val topLevelServiceAsync = client.topLevel() + + val responseFuture = topLevelServiceAsync.helloWorld() + + val response = responseFuture.get() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncTest.kt new file mode 100644 index 00000000..39fa2e1c --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/UserServiceAsyncTest.kt @@ -0,0 +1,46 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.UserRetrieveParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class UserServiceAsyncTest { + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val userServiceAsync = client.users() + + val userFuture = + userServiceAsync.retrieve( + UserRetrieveParams.builder().userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() + ) + + val user = userFuture.get() + user.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val userServiceAsync = client.users() + + val pageFuture = userServiceAsync.list() + + val page = pageFuture.get() + page.response().validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncTest.kt new file mode 100644 index 00000000..829ac4ec --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/ViewServiceAsyncTest.kt @@ -0,0 +1,254 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.ViewCreateParams +import com.braintrustdata.api.models.ViewData +import com.braintrustdata.api.models.ViewDataSearch +import com.braintrustdata.api.models.ViewDeleteParams +import com.braintrustdata.api.models.ViewListParams +import com.braintrustdata.api.models.ViewOptions +import com.braintrustdata.api.models.ViewReplaceParams +import com.braintrustdata.api.models.ViewRetrieveParams +import com.braintrustdata.api.models.ViewUpdateParams +import java.time.OffsetDateTime +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class ViewServiceAsyncTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val viewFuture = + viewServiceAsync.create( + ViewCreateParams.builder() + .name("name") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .viewType(ViewCreateParams.ViewType.PROJECTS) + .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .options( + ViewOptions.builder() + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") + .build() + ) + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .viewData( + ViewData.builder() + .search( + ViewDataSearch.builder() + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) + .build() + ) + .build() + ) + .build() + ) + + val view = viewFuture.get() + view.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val viewFuture = + viewServiceAsync.retrieve( + ViewRetrieveParams.builder() + .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .build() + ) + + val view = viewFuture.get() + view.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val viewFuture = + viewServiceAsync.update( + ViewUpdateParams.builder() + .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .name("name") + .options( + ViewOptions.builder() + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") + .build() + ) + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .viewData( + ViewData.builder() + .search( + ViewDataSearch.builder() + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) + .build() + ) + .build() + ) + .viewType(ViewUpdateParams.ViewType.PROJECTS) + .build() + ) + + val view = viewFuture.get() + view.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val pageFuture = + viewServiceAsync.list( + ViewListParams.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .build() + ) + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val viewFuture = + viewServiceAsync.delete( + ViewDeleteParams.builder() + .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .build() + ) + + val view = viewFuture.get() + view.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val viewServiceAsync = client.views() + + val viewFuture = + viewServiceAsync.replace( + ViewReplaceParams.builder() + .name("name") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .viewType(ViewReplaceParams.ViewType.PROJECTS) + .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .options( + ViewOptions.builder() + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") + .build() + ) + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .viewData( + ViewData.builder() + .search( + ViewDataSearch.builder() + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) + .build() + ) + .build() + ) + .build() + ) + + val view = viewFuture.get() + view.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncTest.kt new file mode 100644 index 00000000..aad7f865 --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/organizations/MemberServiceAsyncTest.kt @@ -0,0 +1,51 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async.organizations + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.models.OrganizationMemberUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class MemberServiceAsyncTest { + + @Test + fun update() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val memberServiceAsync = client.organizations().members() + + val patchOrganizationMembersOutputFuture = + memberServiceAsync.update( + OrganizationMemberUpdateParams.builder() + .inviteUsers( + OrganizationMemberUpdateParams.InviteUsers.builder() + .addEmail("string") + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addGroupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .groupName("group_name") + .addGroupName("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .sendInviteEmails(true) + .build() + ) + .orgId("org_id") + .orgName("org_name") + .removeUsers( + OrganizationMemberUpdateParams.RemoveUsers.builder() + .addEmail("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + .build() + ) + + val patchOrganizationMembersOutput = patchOrganizationMembersOutputFuture.get() + patchOrganizationMembersOutput.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncTest.kt new file mode 100644 index 00000000..035fda7e --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/async/projects/LogServiceAsyncTest.kt @@ -0,0 +1,188 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.async.projects + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClientAsync +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.FeedbackProjectLogsItem +import com.braintrustdata.api.models.InsertProjectLogsEvent +import com.braintrustdata.api.models.ObjectReference +import com.braintrustdata.api.models.ProjectLogFeedbackParams +import com.braintrustdata.api.models.ProjectLogFetchParams +import com.braintrustdata.api.models.ProjectLogFetchPostParams +import com.braintrustdata.api.models.ProjectLogInsertParams +import com.braintrustdata.api.models.SpanAttributes +import com.braintrustdata.api.models.SpanType +import java.time.OffsetDateTime +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class LogServiceAsyncTest { + + @Test + fun feedback() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.projects().logs() + + val feedbackResponseSchemaFuture = + logServiceAsync.feedback( + ProjectLogFeedbackParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addFeedback( + FeedbackProjectLogsItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") + .build() + ) + .build() + ) + + val feedbackResponseSchema = feedbackResponseSchemaFuture.get() + feedbackResponseSchema.validate() + } + + @Test + fun fetch() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.projects().logs() + + val fetchProjectLogsEventsResponseFuture = + logServiceAsync.fetch( + ProjectLogFetchParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchProjectLogsEventsResponse = fetchProjectLogsEventsResponseFuture.get() + fetchProjectLogsEventsResponse.validate() + } + + @Test + fun fetchPost() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.projects().logs() + + val fetchProjectLogsEventsResponseFuture = + logServiceAsync.fetchPost( + ProjectLogFetchPostParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .cursor("cursor") + .limit(0L) + .maxRootSpanId("max_root_span_id") + .maxXactId("max_xact_id") + .version("version") + .build() + ) + + val fetchProjectLogsEventsResponse = fetchProjectLogsEventsResponseFuture.get() + fetchProjectLogsEventsResponse.validate() + } + + @Test + fun insert() { + val client = + BraintrustOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val logServiceAsync = client.projects().logs() + + val insertEventsResponseFuture = + logServiceAsync.insert( + ProjectLogInsertParams.builder() + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addEvent( + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata( + InsertProjectLogsEvent.Metadata.builder().model("model").build() + ) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() + .id("id") + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() + ) + .build() + ) + + val insertEventsResponse = insertEventsResponseFuture.get() + insertEventsResponse.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AclServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AclServiceTest.kt index 20c3d3f6..f50e01c6 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AclServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AclServiceTest.kt @@ -4,157 +4,161 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* +import com.braintrustdata.api.models.AclBatchUpdateParams +import com.braintrustdata.api.models.AclCreateParams +import com.braintrustdata.api.models.AclDeleteParams +import com.braintrustdata.api.models.AclFindAndDeleteParams import com.braintrustdata.api.models.AclListParams +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.AclRetrieveParams +import com.braintrustdata.api.models.Permission import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class AclServiceTest { +internal class AclServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() + val acl = aclService.create( AclCreateParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclCreateParams.Permission.CREATE) - .restrictObjectType(AclCreateParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(acl) + acl.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() + val acl = aclService.retrieve( AclRetrieveParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(acl) + acl.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() - val response = + + val page = aclService.list( AclListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() ) - println(response) - response.objects().forEach { it.validate() } + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() + val acl = aclService.delete( AclDeleteParams.builder().aclId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(acl) + acl.validate() } @Test - fun callBatchUpdate() { + fun batchUpdate() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() + val aclBatchUpdateResponse = aclService.batchUpdate( AclBatchUpdateParams.builder() - .addAcls( - listOf( - AclBatchUpdateParams.AddAcl.builder() - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.AddAcl.ObjectType.ORGANIZATION) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.AddAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.AddAcl.RestrictObjectType.ORGANIZATION - ) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) + .addAddAcl( + AclBatchUpdateParams.AddAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) - .removeAcls( - listOf( - AclBatchUpdateParams.RemoveAcl.builder() - .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclBatchUpdateParams.RemoveAcl.ObjectType.ORGANIZATION) - .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclBatchUpdateParams.RemoveAcl.Permission.CREATE) - .restrictObjectType( - AclBatchUpdateParams.RemoveAcl.RestrictObjectType.ORGANIZATION - ) - .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - ) + .addRemoveAcl( + AclBatchUpdateParams.RemoveAcl.builder() + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(AclObjectType.ORGANIZATION) + .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() ) .build() ) - println(aclBatchUpdateResponse) + aclBatchUpdateResponse.validate() } @Test - fun callFindAndDelete() { + fun findAndDelete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aclService = client.acls() + val acl = aclService.findAndDelete( AclFindAndDeleteParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(AclFindAndDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .permission(AclFindAndDeleteParams.Permission.CREATE) - .restrictObjectType(AclFindAndDeleteParams.RestrictObjectType.ORGANIZATION) + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(acl) + acl.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceTest.kt index 2eb15e81..6d9e6bd1 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/AiSecretServiceTest.kt @@ -4,142 +4,166 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.AiSecretListParams +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AiSecretCreateParams +import com.braintrustdata.api.models.AiSecretDeleteParams +import com.braintrustdata.api.models.AiSecretFindAndDeleteParams +import com.braintrustdata.api.models.AiSecretReplaceParams +import com.braintrustdata.api.models.AiSecretRetrieveParams +import com.braintrustdata.api.models.AiSecretUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class AiSecretServiceTest { +internal class AiSecretServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.create( AiSecretCreateParams.builder() .name("name") - .metadata(AiSecretCreateParams.Metadata.builder().build()) + .metadata( + AiSecretCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") .build() ) - println(aISecret) + aISecret.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.retrieve( AiSecretRetrieveParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(aISecret) + aISecret.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.update( AiSecretUpdateParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .metadata(AiSecretUpdateParams.Metadata.builder().build()) + .metadata( + AiSecretUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .secret("secret") .type("type") .build() ) - println(aISecret) + aISecret.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() - val response = aiSecretService.list(AiSecretListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = aiSecretService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.delete( AiSecretDeleteParams.builder() .aiSecretId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(aISecret) + aISecret.validate() } @Test - fun callFindAndDelete() { + fun findAndDelete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.findAndDelete( AiSecretFindAndDeleteParams.builder().name("name").orgName("org_name").build() ) - println(aISecret) + aISecret.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val aiSecretService = client.aiSecrets() + val aISecret = aiSecretService.replace( AiSecretReplaceParams.builder() .name("name") - .metadata(AiSecretReplaceParams.Metadata.builder().build()) + .metadata( + AiSecretReplaceParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .orgName("org_name") .secret("secret") .type("type") .build() ) - println(aISecret) + aISecret.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceTest.kt index bef46629..953d839e 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ApiKeyServiceTest.kt @@ -4,76 +4,81 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.ApiKeyListParams +import com.braintrustdata.api.models.ApiKeyCreateParams +import com.braintrustdata.api.models.ApiKeyDeleteParams +import com.braintrustdata.api.models.ApiKeyRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ApiKeyServiceTest { +internal class ApiKeyServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val apiKeyService = client.apiKeys() + val createApiKeyOutput = apiKeyService.create( ApiKeyCreateParams.builder().name("name").orgName("org_name").build() ) - println(createApiKeyOutput) + createApiKeyOutput.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val apiKeyService = client.apiKeys() + val apiKey = apiKeyService.retrieve( ApiKeyRetrieveParams.builder() .apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(apiKey) + apiKey.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val apiKeyService = client.apiKeys() - val response = apiKeyService.list(ApiKeyListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = apiKeyService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val apiKeyService = client.apiKeys() + val apiKey = apiKeyService.delete( ApiKeyDeleteParams.builder() .apiKeyId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(apiKey) + apiKey.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceTest.kt index 8a9ef54d..3f79928e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/DatasetServiceTest.kt @@ -4,231 +4,263 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.DatasetListParams +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.DatasetCreateParams +import com.braintrustdata.api.models.DatasetDeleteParams +import com.braintrustdata.api.models.DatasetFeedbackParams +import com.braintrustdata.api.models.DatasetFetchParams +import com.braintrustdata.api.models.DatasetFetchPostParams +import com.braintrustdata.api.models.DatasetInsertParams +import com.braintrustdata.api.models.DatasetRetrieveParams +import com.braintrustdata.api.models.DatasetSummarizeParams +import com.braintrustdata.api.models.DatasetUpdateParams +import com.braintrustdata.api.models.FeedbackDatasetItem +import com.braintrustdata.api.models.InsertDatasetEvent +import com.braintrustdata.api.models.ObjectReference import java.time.OffsetDateTime import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class DatasetServiceTest { +internal class DatasetServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val dataset = datasetService.create( DatasetCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") + .metadata( + DatasetCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .build() ) - println(dataset) + dataset.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val dataset = datasetService.retrieve( DatasetRetrieveParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(dataset) + dataset.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val dataset = datasetService.update( DatasetUpdateParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .metadata(DatasetUpdateParams.Metadata.builder().build()) + .metadata( + DatasetUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .build() ) - println(dataset) + dataset.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() - val response = datasetService.list(DatasetListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = datasetService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val dataset = datasetService.delete( DatasetDeleteParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(dataset) + dataset.validate() } @Test - fun callFeedback() { + fun feedback() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val feedbackResponseSchema = datasetService.feedback( DatasetFeedbackParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackDatasetItem.builder() - .id("id") - .comment("comment") - .metadata(FeedbackDatasetItem.Metadata.builder().build()) - .source(FeedbackDatasetItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackDatasetItem.builder() + .id("id") + .comment("comment") + .metadata( + FeedbackDatasetItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .source(FeedbackDatasetItem.Source.APP) + .addTag("string") + .build() ) .build() ) - println(feedbackResponseSchema) + feedbackResponseSchema.validate() } @Test - fun callFetch() { + fun fetch() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val fetchDatasetEventsResponse = datasetService.fetch( DatasetFetchParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchDatasetEventsResponse) + fetchDatasetEventsResponse.validate() } @Test - fun callFetchPost() { + fun fetchPost() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val fetchDatasetEventsResponse = datasetService.fetchPost( DatasetFetchPostParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchDatasetEventsResponse) + fetchDatasetEventsResponse.validate() } @Test - fun callInsert() { + fun insert() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val insertEventsResponse = datasetService.insert( DatasetInsertParams.builder() .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - DatasetInsertParams.Event.ofInsertDatasetEventReplace( - InsertDatasetEventReplace.builder() + .addEvent( + InsertDatasetEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata(InsertDatasetEvent.Metadata.builder().model("model").build()) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata(InsertDatasetEventReplace.Metadata.builder().build()) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") .build() ) - ) + .rootSpanId("root_span_id") + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() ) - println(insertEventsResponse) + insertEventsResponse.validate() } @Test - fun callSummarize() { + fun summarize() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val datasetService = client.datasets() + val summarizeDatasetResponse = datasetService.summarize( DatasetSummarizeParams.builder() @@ -236,7 +268,7 @@ class DatasetServiceTest { .summarizeData(true) .build() ) - println(summarizeDatasetResponse) + summarizeDatasetResponse.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceTest.kt index 81350114..77382bfc 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EnvVarServiceTest.kt @@ -4,21 +4,28 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* +import com.braintrustdata.api.models.EnvVarCreateParams +import com.braintrustdata.api.models.EnvVarDeleteParams +import com.braintrustdata.api.models.EnvVarListParams +import com.braintrustdata.api.models.EnvVarObjectType +import com.braintrustdata.api.models.EnvVarReplaceParams +import com.braintrustdata.api.models.EnvVarRetrieveParams +import com.braintrustdata.api.models.EnvVarUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class EnvVarServiceTest { +internal class EnvVarServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() + val envVar = envVarService.create( EnvVarCreateParams.builder() @@ -28,36 +35,38 @@ class EnvVarServiceTest { .value("value") .build() ) - println(envVar) + envVar.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() + val envVar = envVarService.retrieve( EnvVarRetrieveParams.builder() .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(envVar) + envVar.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() + val envVar = envVarService.update( EnvVarUpdateParams.builder() @@ -66,57 +75,61 @@ class EnvVarServiceTest { .value("value") .build() ) - println(envVar) + envVar.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() - val envVarListResponse = + + val envVar = envVarService.list( EnvVarListParams.builder() .envVarName("env_var_name") - .limit(123L) + .ids("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .limit(0L) .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(EnvVarListParams.ObjectType.ORGANIZATION) + .objectType(EnvVarObjectType.ORGANIZATION) .build() ) - println(envVarListResponse) - envVarListResponse.validate() + + envVar.validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() + val envVar = envVarService.delete( EnvVarDeleteParams.builder() .envVarId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(envVar) + envVar.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val envVarService = client.envVars() + val envVar = envVarService.replace( EnvVarReplaceParams.builder() @@ -126,7 +139,7 @@ class EnvVarServiceTest { .value("value") .build() ) - println(envVar) + envVar.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EvalServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EvalServiceTest.kt index c2ee858f..2409d221 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EvalServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/EvalServiceTest.kt @@ -4,56 +4,106 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.EvalCreateParams +import com.braintrustdata.api.models.RepoInfo import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class EvalServiceTest { +internal class EvalServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val evalService = client.evals() + val summarizeExperimentResponse = evalService.create( EvalCreateParams.builder() .data( - EvalCreateParams.Data.ofDatasetId( - EvalCreateParams.Data.DatasetId.builder() - .datasetId("dataset_id") - .build() - ) - ) - .projectId("project_id") - .scores( - listOf( - EvalCreateParams.Score.ofFunctionId( - EvalCreateParams.Score.FunctionId.builder() - .functionId("function_id") - .version("version") + EvalCreateParams.Data.DatasetId.builder() + .datasetId("dataset_id") + ._internalBtql( + EvalCreateParams.Data.DatasetId._InternalBtql + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) .build() ) - ) + .build() + ) + .projectId("project_id") + .addScore( + EvalCreateParams.Score.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) .task( - EvalCreateParams.Task.ofFunctionId( - EvalCreateParams.Task.FunctionId.builder() - .functionId("function_id") - .version("version") - .build() - ) + EvalCreateParams.Task.FunctionId.builder() + .functionId("function_id") + .version("version") + .build() ) + .baseExperimentId("base_experiment_id") + .baseExperimentName("base_experiment_name") .experimentName("experiment_name") - .metadata(EvalCreateParams.Metadata.builder().build()) + .gitMetadataSettings( + EvalCreateParams.GitMetadataSettings.builder() + .collect(EvalCreateParams.GitMetadataSettings.Collect.ALL) + .addField(EvalCreateParams.GitMetadataSettings.Field.COMMIT) + .build() + ) + .isPublic(true) + .maxConcurrency(0.0) + .metadata( + EvalCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .parent( + EvalCreateParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + EvalCreateParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + EvalCreateParams.Parent.SpanParentStruct.PropagatedEvent.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + EvalCreateParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() + ) + .repoInfo( + RepoInfo.builder() + .authorEmail("author_email") + .authorName("author_name") + .branch("branch") + .commit("commit") + .commitMessage("commit_message") + .commitTime("commit_time") + .dirty(true) + .gitDiff("git_diff") + .tag("tag") + .build() + ) .stream(true) + .timeout(0.0) + .trialCount(0.0) .build() ) - println(summarizeExperimentResponse) + summarizeExperimentResponse.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceTest.kt index 878d2ace..1f41453e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ExperimentServiceTest.kt @@ -4,24 +4,38 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.ExperimentListParams +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.ExperimentCreateParams +import com.braintrustdata.api.models.ExperimentDeleteParams +import com.braintrustdata.api.models.ExperimentFeedbackParams +import com.braintrustdata.api.models.ExperimentFetchParams +import com.braintrustdata.api.models.ExperimentFetchPostParams +import com.braintrustdata.api.models.ExperimentInsertParams +import com.braintrustdata.api.models.ExperimentRetrieveParams +import com.braintrustdata.api.models.ExperimentSummarizeParams +import com.braintrustdata.api.models.ExperimentUpdateParams +import com.braintrustdata.api.models.FeedbackExperimentItem +import com.braintrustdata.api.models.InsertExperimentEvent +import com.braintrustdata.api.models.ObjectReference +import com.braintrustdata.api.models.RepoInfo +import com.braintrustdata.api.models.SpanAttributes +import com.braintrustdata.api.models.SpanType import java.time.OffsetDateTime import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ExperimentServiceTest { +internal class ExperimentServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val experiment = experimentService.create( ExperimentCreateParams.builder() @@ -31,8 +45,12 @@ class ExperimentServiceTest { .datasetVersion("dataset_version") .description("description") .ensureNew(true) - .metadata(ExperimentCreateParams.Metadata.builder().build()) - .name("name") + .metadata( + ExperimentCreateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .name("x") .public_(true) .repoInfo( RepoInfo.builder() @@ -49,36 +67,38 @@ class ExperimentServiceTest { ) .build() ) - println(experiment) + experiment.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val experiment = experimentService.retrieve( ExperimentRetrieveParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(experiment) + experiment.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val experiment = experimentService.update( ExperimentUpdateParams.builder() @@ -87,7 +107,11 @@ class ExperimentServiceTest { .datasetId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .datasetVersion("dataset_version") .description("description") - .metadata(ExperimentUpdateParams.Metadata.builder().build()) + .metadata( + ExperimentUpdateParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) .name("name") .public_(true) .repoInfo( @@ -105,198 +129,213 @@ class ExperimentServiceTest { ) .build() ) - println(experiment) + experiment.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() - val response = experimentService.list(ExperimentListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = experimentService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val experiment = experimentService.delete( ExperimentDeleteParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(experiment) + experiment.validate() } @Test - fun callFeedback() { + fun feedback() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val feedbackResponseSchema = experimentService.feedback( ExperimentFeedbackParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackExperimentItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackExperimentItem.Metadata.builder().build()) - .scores(FeedbackExperimentItem.Scores.builder().build()) - .source(FeedbackExperimentItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackExperimentItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackExperimentItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackExperimentItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackExperimentItem.Source.APP) + .addTag("string") + .build() ) .build() ) - println(feedbackResponseSchema) + feedbackResponseSchema.validate() } @Test - fun callFetch() { + fun fetch() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val fetchExperimentEventsResponse = experimentService.fetch( ExperimentFetchParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchExperimentEventsResponse) + fetchExperimentEventsResponse.validate() } @Test - fun callFetchPost() { + fun fetchPost() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val fetchExperimentEventsResponse = experimentService.fetchPost( ExperimentFetchPostParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchExperimentEventsResponse) + fetchExperimentEventsResponse.validate() } @Test - fun callInsert() { + fun insert() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val insertEventsResponse = experimentService.insert( ExperimentInsertParams.builder() .experimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ExperimentInsertParams.Event.ofInsertExperimentEventReplace( - InsertExperimentEventReplace.builder() + .addEvent( + InsertExperimentEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertExperimentEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata( + InsertExperimentEvent.Metadata.builder().model("model").build() + ) + .metrics( + InsertExperimentEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertExperimentEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .datasetRecordId("dataset_record_id") - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata( - InsertExperimentEventReplace.Metadata.builder().build() - ) - .metrics( - InsertExperimentEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertExperimentEventReplace.Scores.builder().build()) - .spanAttributes( - InsertExperimentEventReplace.SpanAttributes.builder() - .name("name") - .type( - InsertExperimentEventReplace.SpanAttributes.Type.LLM - ) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertExperimentEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) .build() ) - ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() ) - println(insertEventsResponse) + insertEventsResponse.validate() } @Test - fun callSummarize() { + fun summarize() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val experimentService = client.experiments() + val summarizeExperimentResponse = experimentService.summarize( ExperimentSummarizeParams.builder() @@ -305,7 +344,7 @@ class ExperimentServiceTest { .summarizeScores(true) .build() ) - println(summarizeExperimentResponse) + summarizeExperimentResponse.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceTest.kt index 91a974ad..5666dd34 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/FunctionServiceTest.kt @@ -4,94 +4,104 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.FunctionListParams +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.FunctionCreateParams +import com.braintrustdata.api.models.FunctionDeleteParams +import com.braintrustdata.api.models.FunctionInvokeParams +import com.braintrustdata.api.models.FunctionReplaceParams +import com.braintrustdata.api.models.FunctionRetrieveParams +import com.braintrustdata.api.models.FunctionUpdateParams +import com.braintrustdata.api.models.PromptData +import com.braintrustdata.api.models.PromptOptions +import kotlin.jvm.optionals.getOrNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class FunctionServiceTest { +internal class FunctionServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() + val function = functionService.create( FunctionCreateParams.builder() .functionData( - FunctionCreateParams.FunctionData.ofPrompt( - FunctionCreateParams.FunctionData.Prompt.builder() - .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionCreateParams.FunctionData.Prompt.builder() + .type(FunctionCreateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionCreateParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionCreateParams.FunctionType.LLM) .origin( FunctionCreateParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionCreateParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -105,120 +115,121 @@ class FunctionServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() ) - println(function) + function.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() + val function = functionService.retrieve( FunctionRetrieveParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(function) + function.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() + val function = functionService.update( FunctionUpdateParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") .functionData( - FunctionUpdateParams.FunctionData.ofPrompt( - FunctionUpdateParams.FunctionData.Prompt.builder() - .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionUpdateParams.FunctionData.Prompt.builder() + .type(FunctionUpdateParams.FunctionData.Prompt.Type.PROMPT) + .build() ) .name("name") .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -232,203 +243,208 @@ class FunctionServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() ) - println(function) + function.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() - val response = functionService.list(FunctionListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = functionService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() + val function = functionService.delete( FunctionDeleteParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(function) + function.validate() } @Test - fun callInvoke() { + fun invoke() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() - val functionInvokeResponse = + + val response = functionService.invoke( FunctionInvokeParams.builder() .functionId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .input(JsonNull.of()) - .messages( - listOf( - FunctionInvokeParams.Message.ofSystem( - FunctionInvokeParams.Message.System.builder() - .role(FunctionInvokeParams.Message.System.Role.SYSTEM) - .content("content") - .name("name") - .build() - ) - ) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .addMessage( + FunctionInvokeParams.Message.System.builder() + .role(FunctionInvokeParams.Message.System.Role.SYSTEM) + .content("content") + .name("name") + .build() + ) + .metadata( + FunctionInvokeParams.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() ) .mode(FunctionInvokeParams.Mode.AUTO) .parent( - FunctionInvokeParams.Parent.ofSpanParentStruct( - FunctionInvokeParams.Parent.SpanParentStruct.builder() - .objectId("object_id") - .objectType( - FunctionInvokeParams.Parent.SpanParentStruct.ObjectType - .PROJECT_LOGS - ) - .propagatedEvent( - FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent - .builder() - .build() - ) - .rowIds( - FunctionInvokeParams.Parent.SpanParentStruct.RowIds.builder() - .id("id") - .rootSpanId("root_span_id") - .spanId("span_id") - .build() - ) - .build() - ) + FunctionInvokeParams.Parent.SpanParentStruct.builder() + .objectId("object_id") + .objectType( + FunctionInvokeParams.Parent.SpanParentStruct.ObjectType.PROJECT_LOGS + ) + .propagatedEvent( + FunctionInvokeParams.Parent.SpanParentStruct.PropagatedEvent + .builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .rowIds( + FunctionInvokeParams.Parent.SpanParentStruct.RowIds.builder() + .id("id") + .rootSpanId("root_span_id") + .spanId("span_id") + .build() + ) + .build() ) .stream(true) .version("version") .build() ) - println(functionInvokeResponse) + + val unwrappedResponse = response.getOrNull() + unwrappedResponse?.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val functionService = client.functions() + val function = functionService.replace( FunctionReplaceParams.builder() .functionData( - FunctionReplaceParams.FunctionData.ofPrompt( - FunctionReplaceParams.FunctionData.Prompt.builder() - .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) - .build() - ) + FunctionReplaceParams.FunctionData.Prompt.builder() + .type(FunctionReplaceParams.FunctionData.Prompt.Type.PROMPT) + .build() ) - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionSchema( FunctionReplaceParams.FunctionSchema.builder() - .parameters(JsonNull.of()) - .returns(JsonNull.of()) + .parameters(JsonValue.from(mapOf())) + .returns(JsonValue.from(mapOf())) .build() ) .functionType(FunctionReplaceParams.FunctionType.LLM) .origin( FunctionReplaceParams.Origin.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(FunctionReplaceParams.Origin.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .internal_(true) .build() ) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -442,35 +458,33 @@ class FunctionServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() ) - println(function) + function.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/GroupServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/GroupServiceTest.kt index 197a6890..ef587787 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/GroupServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/GroupServiceTest.kt @@ -4,126 +4,135 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.GroupListParams +import com.braintrustdata.api.models.GroupCreateParams +import com.braintrustdata.api.models.GroupDeleteParams +import com.braintrustdata.api.models.GroupReplaceParams +import com.braintrustdata.api.models.GroupRetrieveParams +import com.braintrustdata.api.models.GroupUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class GroupServiceTest { +internal class GroupServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() + val group = groupService.create( GroupCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() ) - println(group) + group.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() + val group = groupService.retrieve( GroupRetrieveParams.builder() .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(group) + group.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() + val group = groupService.update( GroupUpdateParams.builder() .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .addMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAddMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .removeMemberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .name("x") + .addRemoveMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addRemoveMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(group) + group.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() - val response = groupService.list(GroupListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = groupService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() + val group = groupService.delete( GroupDeleteParams.builder().groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(group) + group.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val groupService = client.groups() + val group = groupService.replace( GroupReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberGroups(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) - .memberUsers(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberGroup("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addMemberUser("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() ) - println(group) + group.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceTest.kt index 17bcb9d2..35ab34c7 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/OrganizationServiceTest.kt @@ -4,40 +4,43 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.OrganizationListParams +import com.braintrustdata.api.models.OrganizationDeleteParams +import com.braintrustdata.api.models.OrganizationRetrieveParams +import com.braintrustdata.api.models.OrganizationUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class OrganizationServiceTest { +internal class OrganizationServiceTest { @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val organizationService = client.organizations() + val organization = organizationService.retrieve( OrganizationRetrieveParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(organization) + organization.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val organizationService = client.organizations() + val organization = organizationService.update( OrganizationUpdateParams.builder() @@ -49,38 +52,40 @@ class OrganizationServiceTest { .realtimeUrl("realtime_url") .build() ) - println(organization) + organization.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val organizationService = client.organizations() - val response = organizationService.list(OrganizationListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = organizationService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val organizationService = client.organizations() + val organization = organizationService.delete( OrganizationDeleteParams.builder() .organizationId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(organization) + organization.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceTest.kt index 5a915482..e09d814c 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectScoreServiceTest.kt @@ -4,53 +4,54 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.ProjectScoreListParams +import com.braintrustdata.api.models.OnlineScoreConfig +import com.braintrustdata.api.models.ProjectScoreCategory +import com.braintrustdata.api.models.ProjectScoreConfig +import com.braintrustdata.api.models.ProjectScoreCreateParams +import com.braintrustdata.api.models.ProjectScoreDeleteParams +import com.braintrustdata.api.models.ProjectScoreReplaceParams +import com.braintrustdata.api.models.ProjectScoreRetrieveParams +import com.braintrustdata.api.models.ProjectScoreType +import com.braintrustdata.api.models.ProjectScoreUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ProjectScoreServiceTest { +internal class ProjectScoreServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() + val projectScore = projectScoreService.create( ProjectScoreCreateParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type - .FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -58,65 +59,60 @@ class ProjectScoreServiceTest { .description("description") .build() ) - println(projectScore) + projectScore.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() + val projectScore = projectScoreService.retrieve( ProjectScoreRetrieveParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(projectScore) + projectScore.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() + val projectScore = projectScoreService.update( ProjectScoreUpdateParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type - .FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -126,80 +122,76 @@ class ProjectScoreServiceTest { .scoreType(ProjectScoreType.SLIDER) .build() ) - println(projectScore) + projectScore.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() - val response = projectScoreService.list(ProjectScoreListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = projectScoreService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() + val projectScore = projectScoreService.delete( ProjectScoreDeleteParams.builder() .projectScoreId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(projectScore) + projectScore.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectScoreService = client.projectScores() + val projectScore = projectScoreService.replace( ProjectScoreReplaceParams.builder() .name("name") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .scoreType(ProjectScoreType.SLIDER) - .projectScoreCategories( - listOf(ProjectScoreCategory.builder().name("name").value(42.23).build()) + .categoriesOfCategorical( + listOf(ProjectScoreCategory.builder().name("name").value(0.0).build()) ) .config( ProjectScoreConfig.builder() - .destination(ProjectScoreConfig.Destination.EXPECTED) + .destination("destination") .multiSelect(true) .online( OnlineScoreConfig.builder() - .samplingRate(1.0) - .scorers( - listOf( - OnlineScoreConfig.Scorer.ofFunction( - OnlineScoreConfig.Scorer.Function.builder() - .id("id") - .type( - OnlineScoreConfig.Scorer.Function.Type - .FUNCTION - ) - .build() - ) - ) + .samplingRate(0.0) + .addScorer( + OnlineScoreConfig.Scorer.Function.builder() + .id("id") + .type(OnlineScoreConfig.Scorer.Function.Type.FUNCTION) + .build() ) .applyToRootSpan(true) - .applyToSpanNames(listOf("string")) + .addApplyToSpanName("string") .build() ) .build() @@ -207,7 +199,7 @@ class ProjectScoreServiceTest { .description("description") .build() ) - println(projectScore) + projectScore.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceTest.kt index b0793622..8e31fe94 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectServiceTest.kt @@ -4,96 +4,117 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.ProjectListParams +import com.braintrustdata.api.models.ProjectCreateParams +import com.braintrustdata.api.models.ProjectDeleteParams +import com.braintrustdata.api.models.ProjectRetrieveParams +import com.braintrustdata.api.models.ProjectSettings +import com.braintrustdata.api.models.ProjectUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ProjectServiceTest { +internal class ProjectServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectService = client.projects() + val project = projectService.create( - ProjectCreateParams.builder().name("name").orgName("org_name").build() + ProjectCreateParams.builder().name("x").orgName("org_name").build() ) - println(project) + project.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectService = client.projects() + val project = projectService.retrieve( ProjectRetrieveParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(project) + project.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectService = client.projects() + val project = projectService.update( ProjectUpdateParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .name("name") - .settings(ProjectSettings.builder().comparisonKey("comparison_key").build()) + .settings( + ProjectSettings.builder() + .baselineExperimentId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .comparisonKey("comparison_key") + .addSpanFieldOrder( + ProjectSettings.SpanFieldOrder.builder() + .columnId("column_id") + .objectType("object_type") + .position("position") + .layout(ProjectSettings.SpanFieldOrder.Layout.FULL) + .build() + ) + .build() + ) .build() ) - println(project) + project.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectService = client.projects() - val response = projectService.list(ProjectListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = projectService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectService = client.projects() + val project = projectService.delete( ProjectDeleteParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(project) + project.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceTest.kt index bffa8967..709ed83a 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ProjectTagServiceTest.kt @@ -4,22 +4,26 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.ProjectTagListParams +import com.braintrustdata.api.models.ProjectTagCreateParams +import com.braintrustdata.api.models.ProjectTagDeleteParams +import com.braintrustdata.api.models.ProjectTagReplaceParams +import com.braintrustdata.api.models.ProjectTagRetrieveParams +import com.braintrustdata.api.models.ProjectTagUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ProjectTagServiceTest { +internal class ProjectTagServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() + val projectTag = projectTagService.create( ProjectTagCreateParams.builder() @@ -29,36 +33,38 @@ class ProjectTagServiceTest { .description("description") .build() ) - println(projectTag) + projectTag.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() + val projectTag = projectTagService.retrieve( ProjectTagRetrieveParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(projectTag) + projectTag.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() + val projectTag = projectTagService.update( ProjectTagUpdateParams.builder() @@ -68,49 +74,52 @@ class ProjectTagServiceTest { .name("name") .build() ) - println(projectTag) + projectTag.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() - val response = projectTagService.list(ProjectTagListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = projectTagService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() + val projectTag = projectTagService.delete( ProjectTagDeleteParams.builder() .projectTagId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(projectTag) + projectTag.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val projectTagService = client.projectTags() + val projectTag = projectTagService.replace( ProjectTagReplaceParams.builder() @@ -120,7 +129,7 @@ class ProjectTagServiceTest { .description("description") .build() ) - println(projectTag) + projectTag.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/PromptServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/PromptServiceTest.kt index bb5693ea..e972b345 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/PromptServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/PromptServiceTest.kt @@ -4,73 +4,83 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.PromptListParams +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.PromptCreateParams +import com.braintrustdata.api.models.PromptData +import com.braintrustdata.api.models.PromptDeleteParams +import com.braintrustdata.api.models.PromptOptions +import com.braintrustdata.api.models.PromptReplaceParams +import com.braintrustdata.api.models.PromptRetrieveParams +import com.braintrustdata.api.models.PromptUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class PromptServiceTest { +internal class PromptServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() + val prompt = promptService.create( PromptCreateParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptCreateParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -84,64 +94,64 @@ class PromptServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() ) - println(prompt) + prompt.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() + val prompt = promptService.retrieve( PromptRetrieveParams.builder() .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(prompt) + prompt.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() + val prompt = promptService.update( PromptUpdateParams.builder() @@ -151,46 +161,49 @@ class PromptServiceTest { .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -204,129 +217,133 @@ class PromptServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) .slug("slug") - .tags(listOf("string")) + .addTag("string") .build() ) - println(prompt) + prompt.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() - val response = promptService.list(PromptListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = promptService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() + val prompt = promptService.delete( PromptDeleteParams.builder() .promptId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(prompt) + prompt.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val promptService = client.prompts() + val prompt = promptService.replace( PromptReplaceParams.builder() - .name("name") + .name("x") .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .slug("slug") + .slug("x") .description("description") .functionType(PromptReplaceParams.FunctionType.LLM) .promptData( PromptData.builder() .options( - PromptData.Options.builder() + PromptOptions.builder() .model("model") .params( - PromptData.Options.Params.ofOpenAIModelParams( - PromptData.Options.Params.OpenAIModelParams.builder() - .frequencyPenalty(42.23) - .functionCall( - PromptData.Options.Params.OpenAIModelParams - .FunctionCall - .ofAuto( - PromptData.Options.Params - .OpenAIModelParams - .FunctionCall - .Auto - .AUTO - ) - ) - .maxTokens(42.23) - .n(42.23) - .presencePenalty(42.23) - .responseFormat( - PromptData.Options.Params.OpenAIModelParams - .ResponseFormat - .builder() - .type( - PromptData.Options.Params - .OpenAIModelParams - .ResponseFormat - .Type - .JSON_OBJECT - ) - .build() - ) - .stop(listOf("string")) - .temperature(42.23) - .toolChoice(ToolChoice.ofAuto(ToolChoice.Auto.AUTO)) - .topP(42.23) - .useCache(true) - .build() - ) + PromptOptions.Params.OpenAIModelParams.builder() + .frequencyPenalty(0.0) + .functionCall( + PromptOptions.Params.OpenAIModelParams.FunctionCall + .UnionMember0 + .AUTO + ) + .maxCompletionTokens(0.0) + .maxTokens(0.0) + .n(0.0) + .presencePenalty(0.0) + .reasoningEffort( + PromptOptions.Params.OpenAIModelParams + .ReasoningEffort + .LOW + ) + .responseFormat( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .builder() + .type( + PromptOptions.Params.OpenAIModelParams + .ResponseFormat + .JsonObject + .Type + .JSON_OBJECT + ) + .build() + ) + .addStop("string") + .temperature(0.0) + .toolChoice( + PromptOptions.Params.OpenAIModelParams.ToolChoice + .UnionMember0 + .AUTO + ) + .topP(0.0) + .useCache(true) + .build() ) .position("position") .build() @@ -340,35 +357,33 @@ class PromptServiceTest { ) .parser( PromptData.Parser.builder() - .choiceScores(PromptData.Parser.ChoiceScores.builder().build()) + .choiceScores( + PromptData.Parser.ChoiceScores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) .type(PromptData.Parser.Type.LLM_CLASSIFIER) .useCot(true) .build() ) .prompt( - PromptData.Prompt.ofCompletion( - PromptData.Prompt.Completion.builder() - .content("content") - .type(PromptData.Prompt.Completion.Type.COMPLETION) - .build() - ) + PromptData.Prompt.Completion.builder() + .content("content") + .type(PromptData.Prompt.Completion.Type.COMPLETION) + .build() ) - .toolFunctions( - listOf( - PromptData.ToolFunction.ofFunction( - PromptData.ToolFunction.Function.builder() - .id("id") - .type(PromptData.ToolFunction.Function.Type.FUNCTION) - .build() - ) - ) + .addToolFunction( + PromptData.ToolFunction.Function.builder() + .id("id") + .type(PromptData.ToolFunction.Function.Type.FUNCTION) + .build() ) .build() ) - .tags(listOf("string")) + .addTag("string") .build() ) - println(prompt) + prompt.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/RoleServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/RoleServiceTest.kt index 20cdf599..219fd06e 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/RoleServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/RoleServiceTest.kt @@ -4,166 +4,155 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.RoleListParams +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.Permission +import com.braintrustdata.api.models.RoleCreateParams +import com.braintrustdata.api.models.RoleDeleteParams +import com.braintrustdata.api.models.RoleReplaceParams +import com.braintrustdata.api.models.RoleRetrieveParams +import com.braintrustdata.api.models.RoleUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class RoleServiceTest { +internal class RoleServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() + val role = roleService.create( RoleCreateParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleCreateParams.MemberPermission.builder() - .permission(RoleCreateParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleCreateParams.MemberPermission.RestrictObjectType - .ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleCreateParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() ) - println(role) + role.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() + val role = roleService.retrieve( RoleRetrieveParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(role) + role.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() + val role = roleService.update( RoleUpdateParams.builder() .roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addMemberPermissions( - listOf( - RoleUpdateParams.AddMemberPermission.builder() - .permission(RoleUpdateParams.AddMemberPermission.Permission.CREATE) - .restrictObjectType( - RoleUpdateParams.AddMemberPermission.RestrictObjectType - .ORGANIZATION - ) - .build() - ) + .addAddMemberPermission( + RoleUpdateParams.AddMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .addMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addAddMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .description("description") - .name("name") - .removeMemberPermissions( - listOf( - RoleUpdateParams.RemoveMemberPermission.builder() - .permission( - RoleUpdateParams.RemoveMemberPermission.Permission.CREATE - ) - .restrictObjectType( - RoleUpdateParams.RemoveMemberPermission.RestrictObjectType - .ORGANIZATION - ) - .build() - ) + .name("x") + .addRemoveMemberPermission( + RoleUpdateParams.RemoveMemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .removeMemberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addRemoveMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) - println(role) + role.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() - val response = roleService.list(RoleListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = roleService.list() + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() + val role = roleService.delete( RoleDeleteParams.builder().roleId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(role) + role.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val roleService = client.roles() + val role = roleService.replace( RoleReplaceParams.builder() - .name("name") + .name("x") .description("description") - .memberPermissions( - listOf( - RoleReplaceParams.MemberPermission.builder() - .permission(RoleReplaceParams.MemberPermission.Permission.CREATE) - .restrictObjectType( - RoleReplaceParams.MemberPermission.RestrictObjectType - .ORGANIZATION - ) - .build() - ) + .addMemberPermission( + RoleReplaceParams.MemberPermission.builder() + .permission(Permission.CREATE) + .restrictObjectType(AclObjectType.ORGANIZATION) + .build() ) - .memberRoles(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addMemberRole("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .orgName("org_name") .build() ) - println(role) + role.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceTest.kt new file mode 100644 index 00000000..c17eec2b --- /dev/null +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/SpanIframeServiceTest.kt @@ -0,0 +1,138 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.braintrustdata.api.services.blocking + +import com.braintrustdata.api.TestServerExtension +import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient +import com.braintrustdata.api.models.SpanIframeCreateParams +import com.braintrustdata.api.models.SpanIframeDeleteParams +import com.braintrustdata.api.models.SpanIframeReplaceParams +import com.braintrustdata.api.models.SpanIframeRetrieveParams +import com.braintrustdata.api.models.SpanIframeUpdateParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class SpanIframeServiceTest { + + @Test + fun create() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val spanIFrame = + spanIframeService.create( + SpanIframeCreateParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + ) + + spanIFrame.validate() + } + + @Test + fun retrieve() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val spanIFrame = + spanIframeService.retrieve( + SpanIframeRetrieveParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + spanIFrame.validate() + } + + @Test + fun update() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val spanIFrame = + spanIframeService.update( + SpanIframeUpdateParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .description("description") + .name("name") + .postMessage(true) + .url("url") + .build() + ) + + spanIFrame.validate() + } + + @Test + fun list() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val page = spanIframeService.list() + + page.response().validate() + } + + @Test + fun delete() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val spanIFrame = + spanIframeService.delete( + SpanIframeDeleteParams.builder() + .spanIframeId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + spanIFrame.validate() + } + + @Test + fun replace() { + val client = + BraintrustOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val spanIframeService = client.spanIframes() + + val spanIFrame = + spanIframeService.replace( + SpanIframeReplaceParams.builder() + .name("name") + .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .url("url") + .description("description") + .postMessage(true) + .build() + ) + + spanIFrame.validate() + } +} diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceTest.kt index ab277bdc..de7c1385 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/TopLevelServiceTest.kt @@ -4,25 +4,21 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class TopLevelServiceTest { +internal class TopLevelServiceTest { @Test - fun callHelloWorld() { + fun helloWorld() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val topLevelService = client.topLevel() - val topLevelHelloWorldResponse = - topLevelService.helloWorld(TopLevelHelloWorldParams.builder().build()) - println(topLevelHelloWorldResponse) - assertThat(topLevelHelloWorldResponse).isNotBlank() + + topLevelService.helloWorld() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/UserServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/UserServiceTest.kt index 24f732e2..70032d95 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/UserServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/UserServiceTest.kt @@ -4,40 +4,41 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* -import com.braintrustdata.api.models.UserListParams +import com.braintrustdata.api.models.UserRetrieveParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class UserServiceTest { +internal class UserServiceTest { @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val userService = client.users() + val user = userService.retrieve( UserRetrieveParams.builder().userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e").build() ) - println(user) + user.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val userService = client.users() - val response = userService.list(UserListParams.builder().build()) - println(response) - response.objects().forEach { it.validate() } + + val page = userService.list() + + page.response().validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ViewServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ViewServiceTest.kt index 5eefd68b..4019925d 100755 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ViewServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/ViewServiceTest.kt @@ -4,37 +4,57 @@ package com.braintrustdata.api.services.blocking import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.AclObjectType +import com.braintrustdata.api.models.ViewCreateParams +import com.braintrustdata.api.models.ViewData +import com.braintrustdata.api.models.ViewDataSearch +import com.braintrustdata.api.models.ViewDeleteParams import com.braintrustdata.api.models.ViewListParams +import com.braintrustdata.api.models.ViewOptions +import com.braintrustdata.api.models.ViewReplaceParams +import com.braintrustdata.api.models.ViewRetrieveParams +import com.braintrustdata.api.models.ViewUpdateParams import java.time.OffsetDateTime import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class ViewServiceTest { +internal class ViewServiceTest { @Test - fun callCreate() { + fun create() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() + val view = viewService.create( ViewCreateParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewCreateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewCreateParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -42,60 +62,73 @@ class ViewServiceTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) .build() ) - println(view) + view.validate() } @Test - fun callRetrieve() { + fun retrieve() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() + val view = viewService.retrieve( ViewRetrieveParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewRetrieveParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() ) - println(view) + view.validate() } @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() + val view = viewService.update( ViewUpdateParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewUpdateParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .name("name") .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -103,10 +136,10 @@ class ViewServiceTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() @@ -114,70 +147,84 @@ class ViewServiceTest { .viewType(ViewUpdateParams.ViewType.PROJECTS) .build() ) - println(view) + view.validate() } @Test - fun callList() { + fun list() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() - val response = + + val page = viewService.list( ViewListParams.builder() .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewListParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() ) - println(response) - response.objects().forEach { it.validate() } + + page.response().validate() } @Test - fun callDelete() { + fun delete() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() + val view = viewService.delete( ViewDeleteParams.builder() .viewId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewDeleteParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .build() ) - println(view) + view.validate() } @Test - fun callReplace() { + fun replace() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val viewService = client.views() + val view = viewService.replace( ViewReplaceParams.builder() .name("name") .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .objectType(ViewReplaceParams.ObjectType.ORGANIZATION) + .objectType(AclObjectType.ORGANIZATION) .viewType(ViewReplaceParams.ViewType.PROJECTS) .deletedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) .options( ViewOptions.builder() - .columnOrder(listOf("string")) - .columnSizing(ViewOptions.ColumnSizing.builder().build()) - .columnVisibility(ViewOptions.ColumnVisibility.builder().build()) + .addColumnOrder("string") + .columnSizing( + ViewOptions.ColumnSizing.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .columnVisibility( + ViewOptions.ColumnVisibility.builder() + .putAdditionalProperty("foo", JsonValue.from(true)) + .build() + ) + .grouping("grouping") + .layout("layout") + .rowHeight("rowHeight") .build() ) .userId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -185,17 +232,17 @@ class ViewServiceTest { ViewData.builder() .search( ViewDataSearch.builder() - .filter(listOf(JsonNull.of())) - .match(listOf(JsonNull.of())) - .sort(listOf(JsonNull.of())) - .tag(listOf(JsonNull.of())) + .addFilter(JsonValue.from(mapOf())) + .addMatch(JsonValue.from(mapOf())) + .addSort(JsonValue.from(mapOf())) + .addTag(JsonValue.from(mapOf())) .build() ) .build() ) .build() ) - println(view) + view.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceTest.kt index 6f12d171..cf30ad12 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/organizations/MemberServiceTest.kt @@ -4,32 +4,33 @@ package com.braintrustdata.api.services.blocking.organizations import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.models.* +import com.braintrustdata.api.models.OrganizationMemberUpdateParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class MemberServiceTest { +internal class MemberServiceTest { @Test - fun callUpdate() { + fun update() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val memberService = client.organizations().members() + val patchOrganizationMembersOutput = memberService.update( OrganizationMemberUpdateParams.builder() .inviteUsers( OrganizationMemberUpdateParams.InviteUsers.builder() - .emails(listOf("string")) + .addEmail("string") .groupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .groupIds(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .groupName("group_name") - .groupNames(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addGroupName("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .sendInviteEmails(true) .build() ) @@ -37,13 +38,13 @@ class MemberServiceTest { .orgName("org_name") .removeUsers( OrganizationMemberUpdateParams.RemoveUsers.builder() - .emails(listOf("string")) - .ids(listOf("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e")) + .addEmail("string") + .addId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .build() ) .build() ) - println(patchOrganizationMembersOutput) + patchOrganizationMembersOutput.validate() } } diff --git a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceTest.kt b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceTest.kt index 21c25964..d0ccaad0 100644 --- a/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceTest.kt +++ b/braintrust-java-core/src/test/kotlin/com/braintrustdata/api/services/blocking/projects/LogServiceTest.kt @@ -4,161 +4,181 @@ package com.braintrustdata.api.services.blocking.projects import com.braintrustdata.api.TestServerExtension import com.braintrustdata.api.client.okhttp.BraintrustOkHttpClient -import com.braintrustdata.api.core.JsonNull -import com.braintrustdata.api.models.* +import com.braintrustdata.api.core.JsonValue +import com.braintrustdata.api.models.FeedbackProjectLogsItem +import com.braintrustdata.api.models.InsertProjectLogsEvent +import com.braintrustdata.api.models.ObjectReference +import com.braintrustdata.api.models.ProjectLogFeedbackParams +import com.braintrustdata.api.models.ProjectLogFetchParams +import com.braintrustdata.api.models.ProjectLogFetchPostParams +import com.braintrustdata.api.models.ProjectLogInsertParams +import com.braintrustdata.api.models.SpanAttributes +import com.braintrustdata.api.models.SpanType import java.time.OffsetDateTime import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(TestServerExtension::class) -class LogServiceTest { +internal class LogServiceTest { @Test - fun callFeedback() { + fun feedback() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val logService = client.projects().logs() + val feedbackResponseSchema = logService.feedback( ProjectLogFeedbackParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .feedback( - listOf( - FeedbackProjectLogsItem.builder() - .id("id") - .comment("comment") - .expected(JsonNull.of()) - .metadata(FeedbackProjectLogsItem.Metadata.builder().build()) - .scores(FeedbackProjectLogsItem.Scores.builder().build()) - .source(FeedbackProjectLogsItem.Source.APP) - .build() - ) + .addFeedback( + FeedbackProjectLogsItem.builder() + .id("id") + .comment("comment") + .expected(JsonValue.from(mapOf())) + .metadata( + FeedbackProjectLogsItem.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .scores( + FeedbackProjectLogsItem.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) + .build() + ) + .source(FeedbackProjectLogsItem.Source.APP) + .addTag("string") + .build() ) .build() ) - println(feedbackResponseSchema) + feedbackResponseSchema.validate() } @Test - fun callFetch() { + fun fetch() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val logService = client.projects().logs() + val fetchProjectLogsEventsResponse = logService.fetch( ProjectLogFetchParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchProjectLogsEventsResponse) + fetchProjectLogsEventsResponse.validate() } @Test - fun callFetchPost() { + fun fetchPost() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val logService = client.projects().logs() + val fetchProjectLogsEventsResponse = logService.fetchPost( ProjectLogFetchPostParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .cursor("cursor") - .filters( - listOf( - PathLookupFilter.builder() - .path(listOf("string")) - .type(PathLookupFilter.Type.PATH_LOOKUP) - .value(JsonNull.of()) - .build() - ) - ) - .limit(123L) + .limit(0L) .maxRootSpanId("max_root_span_id") .maxXactId("max_xact_id") .version("version") .build() ) - println(fetchProjectLogsEventsResponse) + fetchProjectLogsEventsResponse.validate() } @Test - fun callInsert() { + fun insert() { val client = BraintrustOkHttpClient.builder() .baseUrl(TestServerExtension.BASE_URL) .apiKey("My API Key") .build() val logService = client.projects().logs() + val insertEventsResponse = logService.insert( ProjectLogInsertParams.builder() .projectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .events( - listOf( - ProjectLogInsertParams.Event.ofInsertProjectLogsEventReplace( - InsertProjectLogsEventReplace.builder() + .addEvent( + InsertProjectLogsEvent.builder() + .id("id") + ._isMerge(true) + .addMergePath(listOf("string")) + ._objectDelete(true) + ._parentId("_parent_id") + .context( + InsertProjectLogsEvent.Context.builder() + .callerFilename("caller_filename") + .callerFunctionname("caller_functionname") + .callerLineno(0L) + .build() + ) + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .error(JsonValue.from(mapOf())) + .expected(JsonValue.from(mapOf())) + .input(JsonValue.from(mapOf())) + .metadata( + InsertProjectLogsEvent.Metadata.builder().model("model").build() + ) + .metrics( + InsertProjectLogsEvent.Metrics.builder() + .callerFilename(JsonValue.from(mapOf())) + .callerFunctionname(JsonValue.from(mapOf())) + .callerLineno(JsonValue.from(mapOf())) + .completionTokens(0L) + .end(0.0) + .promptTokens(0L) + .start(0.0) + .tokens(0L) + .build() + ) + .origin( + ObjectReference.builder() .id("id") - ._isMerge(true) - ._objectDelete(true) - ._parentId("_parent_id") - .context( - InsertProjectLogsEventReplace.Context.builder() - .callerFilename("caller_filename") - .callerFunctionname("caller_functionname") - .callerLineno(123L) - .build() - ) - .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .error(JsonNull.of()) - .expected(JsonNull.of()) - .input(JsonNull.of()) - .metadata( - InsertProjectLogsEventReplace.Metadata.builder().build() - ) - .metrics( - InsertProjectLogsEventReplace.Metrics.builder() - .completionTokens(123L) - .end(42.23) - .promptTokens(123L) - .start(42.23) - .tokens(123L) - .build() - ) - .output(JsonNull.of()) - .scores(InsertProjectLogsEventReplace.Scores.builder().build()) - .spanAttributes( - InsertProjectLogsEventReplace.SpanAttributes.builder() - .name("name") - .type( - InsertProjectLogsEventReplace.SpanAttributes.Type - .LLM - ) - .build() - ) - .tags(listOf("string")) + ._xactId("_xact_id") + .objectId("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .objectType(ObjectReference.ObjectType.EXPERIMENT) + .created("created") + .build() + ) + .output(JsonValue.from(mapOf())) + .rootSpanId("root_span_id") + .scores( + InsertProjectLogsEvent.Scores.builder() + .putAdditionalProperty("foo", JsonValue.from(0)) .build() ) - ) + .spanAttributes( + SpanAttributes.builder().name("name").type(SpanType.LLM).build() + ) + .spanId("span_id") + .addSpanParent("string") + .addTag("string") + .build() ) .build() ) - println(insertEventsResponse) + insertEventsResponse.validate() } } diff --git a/braintrust-java-example/build.gradle.kts b/braintrust-java-example/build.gradle.kts new file mode 100644 index 00000000..c64a1556 --- /dev/null +++ b/braintrust-java-example/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("braintrust.kotlin") + id("java") + application +} + +dependencies { + implementation(project(":braintrust-java")) +} + +tasks.withType().configureEach { + // Allow using more modern APIs, like `List.of` and `Map.of`, in examples. + options.release.set(9) +} + +application { + mainClass = "com.braintrustdata.api.example.Main" +} diff --git a/braintrust-java/build.gradle.kts b/braintrust-java/build.gradle.kts index ccb65cda..2f936950 100755 --- a/braintrust-java/build.gradle.kts +++ b/braintrust-java/build.gradle.kts @@ -6,3 +6,24 @@ plugins { dependencies { api(project(":braintrust-java-client-okhttp")) } + +// Redefine `dokkaJavadoc` to: +// - Depend on the root project's task for merging the docs of all the projects +// - Forward that task's output to this task's output +tasks.named("dokkaJavadoc").configure { + actions.clear() + + val dokkaJavadocCollector = rootProject.tasks["dokkaJavadocCollector"] + dependsOn(dokkaJavadocCollector) + + val outputDirectory = project.layout.buildDirectory.dir("dokka/javadoc") + doLast { + copy { + from(dokkaJavadocCollector.outputs.files) + into(outputDirectory) + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + } + + outputs.dir(outputDirectory) +} diff --git a/build.gradle.kts b/build.gradle.kts index d33feea6..3a613beb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,23 @@ plugins { + id("org.jetbrains.dokka") version "2.0.0" +} +repositories { + mavenCentral() } allprojects { group = "com.braintrustdata.api" - version = "0.7.0" // x-release-please-version + version = "0.8.0" // x-release-please-version } +subprojects { + apply(plugin = "org.jetbrains.dokka") +} +// Avoid race conditions between `dokkaJavadocCollector` and `dokkaJavadocJar` tasks +tasks.named("dokkaJavadocCollector").configure { + subprojects.flatMap { it.tasks } + .filter { it.project.name != "braintrust-java" && it.name == "dokkaJavadocJar" } + .forEach { mustRunAfter(it) } +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 493cb327..d1ed374d 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `kotlin-dsl` - kotlin("jvm") version "1.9.22" + kotlin("jvm") version "2.1.10" id("com.vanniktech.maven.publish") version "0.28.0" } @@ -10,7 +10,7 @@ repositories { } dependencies { - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.23") + implementation("com.diffplug.spotless:spotless-plugin-gradle:7.0.2") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.10") implementation("com.vanniktech:gradle-maven-publish-plugin:0.28.0") } diff --git a/buildSrc/src/main/kotlin/braintrust.java.gradle.kts b/buildSrc/src/main/kotlin/braintrust.java.gradle.kts index 53e63304..597b6e80 100755 --- a/buildSrc/src/main/kotlin/braintrust.java.gradle.kts +++ b/buildSrc/src/main/kotlin/braintrust.java.gradle.kts @@ -1,9 +1,5 @@ import com.diffplug.gradle.spotless.SpotlessExtension import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import com.vanniktech.maven.publish.JavaLibrary -import com.vanniktech.maven.publish.JavadocJar -import com.vanniktech.maven.publish.MavenPublishBaseExtension -import com.vanniktech.maven.publish.SonatypeHost plugins { `java-library` @@ -19,6 +15,7 @@ configure { importOrder() removeUnusedImports() palantirJavaFormat() + toggleOffOn() } } @@ -42,9 +39,13 @@ tasks.named("jar") { } } -tasks.named("test") { +tasks.withType().configureEach { useJUnitPlatform() + // Run tests in parallel to some degree. + maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1) + forkEvery = 100 + testLogging { exceptionFormat = TestExceptionFormat.FULL } diff --git a/buildSrc/src/main/kotlin/braintrust.kotlin.gradle.kts b/buildSrc/src/main/kotlin/braintrust.kotlin.gradle.kts index 267e3576..ff8a82d8 100755 --- a/buildSrc/src/main/kotlin/braintrust.kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/braintrust.kotlin.gradle.kts @@ -1,6 +1,6 @@ import com.diffplug.gradle.spotless.SpotlessExtension +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import com.vanniktech.maven.publish.* plugins { id("braintrust.java") @@ -16,13 +16,25 @@ kotlin { configure { kotlin { ktfmt().kotlinlangStyle() + toggleOffOn() } } tasks.withType().configureEach { - kotlinOptions { + compilerOptions { allWarningsAsErrors = true - freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=1.8") - jvmTarget = "1.8" + freeCompilerArgs = listOf( + "-Xjvm-default=all", + "-Xjdk-release=1.8", + // Suppress deprecation warnings because we may still reference and test deprecated members. + "-Xsuppress-warning=DEPRECATION" + ) + jvmTarget.set(JvmTarget.JVM_1_8) } } + +// Run tests in parallel to some degree. +tasks.withType().configureEach { + maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1) + forkEvery = 100 +} diff --git a/buildSrc/src/main/kotlin/braintrust.publish.gradle.kts b/buildSrc/src/main/kotlin/braintrust.publish.gradle.kts index 4913adb6..c96736ac 100755 --- a/buildSrc/src/main/kotlin/braintrust.publish.gradle.kts +++ b/buildSrc/src/main/kotlin/braintrust.publish.gradle.kts @@ -1,10 +1,5 @@ -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.register -import org.gradle.kotlin.dsl.get -import com.vanniktech.maven.publish.JavaLibrary import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.KotlinJvm import com.vanniktech.maven.publish.MavenPublishBaseExtension import com.vanniktech.maven.publish.SonatypeHost @@ -25,7 +20,13 @@ configure { signAllPublications() publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) - this.coordinates(project.group.toString(), project.name, project.version.toString()) + coordinates(project.group.toString(), project.name, project.version.toString()) + configure( + KotlinJvm( + javadocJar = JavadocJar.Dokka("dokkaJavadoc"), + sourcesJar = true, + ) + ) pom { name.set("Braintrust API") @@ -41,7 +42,7 @@ configure { developers { developer { name.set("Braintrust") - email.set("info-test@braintrustdata.com") + email.set("info@braintrustdata.com") } } diff --git a/gradle.properties b/gradle.properties index a3bc58f2..0c8d4ded 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ org.gradle.caching=true -org.gradle.jvmargs=-Xmx4g org.gradle.parallel=true +org.gradle.daemon=false +org.gradle.jvmargs=-Xmx4g kotlin.daemon.jvmargs=-Xmx4g diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136..a4b76b95 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..cea7a793 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42..f3b75f3b 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/scripts/format b/scripts/format index c6239fab..456a69db 100755 --- a/scripts/format +++ b/scripts/format @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Running spotlessApply" -./gradlew --build-cache --parallel --no-daemon spotlessApply +./gradlew spotlessApply diff --git a/scripts/lint b/scripts/lint index 58753d0b..e3a5f5e2 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Build classes" -./gradlew --build-cache --parallel --no-daemon build testClasses -x test +./gradlew build testClasses -x test diff --git a/scripts/test b/scripts/test index 72ed0333..6b750a74 100755 --- a/scripts/test +++ b/scripts/test @@ -53,4 +53,4 @@ else fi echo "==> Running tests" -./gradlew --build-cache --parallel --no-daemon test +./gradlew test